Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5636206imu; Mon, 26 Nov 2018 03:19:33 -0800 (PST) X-Google-Smtp-Source: AFSGD/UX++Hjg0yr0UhPLh4d1pPKRGIL9/dm1Xb/vSgVvd2L8mufm5cArjLaD7EEg9rA0Ky+i1lt X-Received: by 2002:a63:981:: with SMTP id 123mr24530739pgj.444.1543231172962; Mon, 26 Nov 2018 03:19:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543231172; cv=none; d=google.com; s=arc-20160816; b=Lc5zaSZG8LjyZKIJ7+6p1sjHG9ngyC0NBsvvEDeJr+6mUBPOIq+W+Gf+dET7i39l25 E6iylfYr89ONgprZjqRu5QZKDvK+trn4NPgRbF0DBtnohWTDKGp5OcjoWSlYZqB3w6AB lFRyg0mgqC91X0UagrJBhbDYLyNCFAKwWCdEI3rAcbK38p24q7Oo+NbF8iah3e02XJTC DhD4e+DeBVImBP7aiD8sh/RXJGup3Jcho4sCLNlAGHn13O89nIH4xn8g5aYnSZn/zQQq y8wIAeI/IcJ2vmx0ZEfpF6S6h4jFAEaEv+qweK9f1BQsyctN2XsnEJS4Fg7oyhD/UFCT pgLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=oAX+FjH1uFkfsHGDpVeqszw2Y+6p+3+e7jUNiQPpeM8=; b=fmvOL1RXaYKjaxnJx1RdAphXKIILHw26YF3DxIEQX/pwjOg8wpKKDf+27cElQIlTBj /lBtCke/t4bj/971bFSHkxk8AV/FRWghuSrPhLJHowEz9i7Bbm9SMWaK16O6V5TIHgqE eckZG/5uPSH6nsyVoZo4bYwohORgjzErzAONphU3d98JZvtv2HVGLz7qFR1mcza7QDLO 119CYaOE7ExRYvUNAAortdKMekJRWf4cSwJdHlZow1cBloQKqXB8Kc8g1SjOnlYvY6Kx WlQQi43C6ni5k65RNvRQaCbB5ko8nB2VvW3BMsOf4KPLRaHFdmhWxRSdOf56xCFT0B0p 5uVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=YQZAJT3x; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i189si38238136pfg.265.2018.11.26.03.18.55; Mon, 26 Nov 2018 03:19:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=YQZAJT3x; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729919AbeKZVya (ORCPT + 99 others); Mon, 26 Nov 2018 16:54:30 -0500 Received: from mail.kernel.org ([198.145.29.99]:36652 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728754AbeKZVy3 (ORCPT ); Mon, 26 Nov 2018 16:54:29 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 340912147D; Mon, 26 Nov 2018 11:00:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543230043; bh=l5fNqY+c/Nj1Jj3zy58M/PbKG3ic+mxfna6t08x6a+w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YQZAJT3x/RgNgARuejLstNGm1PpbgJMMaiV9J6I1U8wCk1ozSrfkxKkBRiBRoC0KW kmXuzgGbVFmW/WMvAIZDwm37xLcih52BPJBbfBAJafNPXL6UTFasli9CtmW0sCIkta PS9VtEbRE/2WVMdte2q7RKtluHUZPfOpW07mnjOs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dave Stevenson , Sakari Ailus , Hans Verkuil , Mauro Carvalho Chehab Subject: [PATCH 4.14 50/62] media: v4l: event: Add subscription to list before calling "add" operation Date: Mon, 26 Nov 2018 11:51:31 +0100 Message-Id: <20181126105054.498319013@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105050.592727680@linuxfoundation.org> References: <20181126105050.592727680@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sakari Ailus commit 92539d3eda2c090b382699bbb896d4b54e9bdece upstream. Patch ad608fbcf166 changed how events were subscribed to address an issue elsewhere. As a side effect of that change, the "add" callback was called before the event subscription was added to the list of subscribed events, causing the first event queued by the add callback (and possibly other events arriving soon afterwards) to be lost. Fix this by adding the subscription to the list before calling the "add" callback, and clean up afterwards if that fails. Fixes: ad608fbcf166 ("media: v4l: event: Prevent freeing event subscriptions while accessed") Reported-by: Dave Stevenson Signed-off-by: Sakari Ailus Tested-by: Dave Stevenson Reviewed-by: Hans Verkuil Tested-by: Hans Verkuil Cc: stable@vger.kernel.org (for 4.14 and up) Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/v4l2-event.c | 43 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c @@ -193,6 +193,22 @@ int v4l2_event_pending(struct v4l2_fh *f } EXPORT_SYMBOL_GPL(v4l2_event_pending); +static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev) +{ + struct v4l2_fh *fh = sev->fh; + unsigned int i; + + lockdep_assert_held(&fh->subscribe_lock); + assert_spin_locked(&fh->vdev->fh_lock); + + /* Remove any pending events for this subscription */ + for (i = 0; i < sev->in_use; i++) { + list_del(&sev->events[sev_pos(sev, i)].list); + fh->navailable--; + } + list_del(&sev->list); +} + int v4l2_event_subscribe(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub, unsigned elems, const struct v4l2_subscribed_event_ops *ops) @@ -225,27 +241,23 @@ int v4l2_event_subscribe(struct v4l2_fh spin_lock_irqsave(&fh->vdev->fh_lock, flags); found_ev = v4l2_event_subscribed(fh, sub->type, sub->id); + if (!found_ev) + list_add(&sev->list, &fh->subscribed); spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); if (found_ev) { /* Already listening */ kvfree(sev); - goto out_unlock; - } - - if (sev->ops && sev->ops->add) { + } else if (sev->ops && sev->ops->add) { ret = sev->ops->add(sev, elems); if (ret) { + spin_lock_irqsave(&fh->vdev->fh_lock, flags); + __v4l2_event_unsubscribe(sev); + spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); kvfree(sev); - goto out_unlock; } } - spin_lock_irqsave(&fh->vdev->fh_lock, flags); - list_add(&sev->list, &fh->subscribed); - spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); - -out_unlock: mutex_unlock(&fh->subscribe_lock); return ret; @@ -280,7 +292,6 @@ int v4l2_event_unsubscribe(struct v4l2_f { struct v4l2_subscribed_event *sev; unsigned long flags; - int i; if (sub->type == V4L2_EVENT_ALL) { v4l2_event_unsubscribe_all(fh); @@ -292,14 +303,8 @@ int v4l2_event_unsubscribe(struct v4l2_f spin_lock_irqsave(&fh->vdev->fh_lock, flags); sev = v4l2_event_subscribed(fh, sub->type, sub->id); - if (sev != NULL) { - /* Remove any pending events for this subscription */ - for (i = 0; i < sev->in_use; i++) { - list_del(&sev->events[sev_pos(sev, i)].list); - fh->navailable--; - } - list_del(&sev->list); - } + if (sev != NULL) + __v4l2_event_unsubscribe(sev); spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);