Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5621974imu; Mon, 26 Nov 2018 03:07:44 -0800 (PST) X-Google-Smtp-Source: AFSGD/XyLj46oauokKk7cMdzwjKLydSpBBa6wJolIPw0Ah7O9w4a0B7rStAMngsYvGthVVSZenUa X-Received: by 2002:a17:902:50e:: with SMTP id 14mr18961925plf.141.1543230464417; Mon, 26 Nov 2018 03:07:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543230464; cv=none; d=google.com; s=arc-20160816; b=l8xJ30tfDyuwUTt3v9DaCEDTMr7RIsXaQcUf2Vx7XWTAf0dSfGI0VgZZy5HDfcr7yb P1RuvKHDnD+05BzsIA/C1HpiGhYfbR14jJqCQANu5oF1ghnlMygaJbIX5M/pmR7Bld/v /NQjZyDY4tMfy3LHBhiTIwdSGQ1O9o5Pk2dWLg8lkNNr2hPBnsq23880IDOERmAwsYWs sfAAUF0DVk0SldH8KllPoEnMBPTmCvBq/Geb5V7jvUzJ58xX77PGUOlKADmVmAk52OcL WPXLLAktRAjXSzpEtmz5/lS4zJxXdpSy4PBsH2k/24GO6oLKBSx6Wd5d+x+a0CxYn6M4 zy9A== 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=kJvBf9Oy4r5/NYksalU0cKjAf1cWnlmQRapyEy/zjAQ=; b=hBTCBHzKsdH/Iltou0qF4iPqZ/DDV+Sdv5srdlImRvfplpXDde36FngDExCimk0OhE JgnzdgMztma9GtTpkPACRM0a+IiOi/vGiABD6ROnklXVrjC6EUiogRt/RDm2ZrLY9OGf jFcGumbLXM8cI+02fvVNSzDG2kXlJywShO1E5TqN7TNRVt8RocyI/3BDSbuNlO4XiEpr 3uJk2fgQ+i7Bc5jdoiPtsg/jvCkHR5fc+CBgPTpczzkxjpeWct7ivL3h1Q+nr5xcv0dx uxDSFgmyUEt2gR+VfqtdicakenpaSfuO8+IPcPeW7mUv8sKkllP7M+BzQhqMXmYtDwJV 6h3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Wz67+zJc; 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 g22si57372137pfj.222.2018.11.26.03.07.30; Mon, 26 Nov 2018 03:07:44 -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=Wz67+zJc; 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 S1731327AbeKZV7S (ORCPT + 99 others); Mon, 26 Nov 2018 16:59:18 -0500 Received: from mail.kernel.org ([198.145.29.99]:45234 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730303AbeKZV7S (ORCPT ); Mon, 26 Nov 2018 16:59:18 -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 2775820645; Mon, 26 Nov 2018 11:05:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543230331; bh=WPsfhAPN2NLTdQcQg6jcYNSZgTjkCJ3R6jma/u3ju6o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wz67+zJcQOwPf4fiiLDSbDfp5cs3SlyAyLvABnCk0u8Q9paUUfizZCtpZZQ107gxh X0pEwK8TzwyfC4up43F76jMRdhF9x1Hlv5lkMfjFm28Cq8afs5MT+cHZWMkkVafAQo 2HmzSk87M9BSmFK+GeQ2+llEg7nLI4gxavhof4X8= 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.19 095/118] media: v4l: event: Add subscription to list before calling "add" operation Date: Mon, 26 Nov 2018 11:51:29 +0100 Message-Id: <20181126105105.509563700@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105059.832485122@linuxfoundation.org> References: <20181126105059.832485122@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.19-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) @@ -224,27 +240,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; @@ -279,7 +291,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); @@ -291,14 +302,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);