Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5638871imu; Mon, 26 Nov 2018 03:22:03 -0800 (PST) X-Google-Smtp-Source: AFSGD/UCUmupLqwtEUJ09gmsxQO1r+N2Biah5QDlphrBdNA2poQ/TZ9RzQfXOZjDec7d5VvL8aBb X-Received: by 2002:a17:902:6b03:: with SMTP id o3-v6mr27171531plk.208.1543231323099; Mon, 26 Nov 2018 03:22:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543231323; cv=none; d=google.com; s=arc-20160816; b=rUYSTKKjQemr0HuY0dpC1IL+hT+i2gZL9bxHl8BrBDd+YWY/D7eFqw6JQ4HGms6Xjf hsQV7PZKjh4oDYmaBTgyUpiW/qfbDzH7tfpXkS4gxiiK9auaM8Ub0NYQMh4gPc6rvNSN 5PNZRhUJbIqK8WEgH4Mdtp9FT/p/Z9ItX7ZbgMbTjtuh6ATCfzyPOMWIquFBtKxmoEZd OzcupPK72e9m8yM/zPaLRRq/Wf078joa4GV13JSiuo8m1j8ucbPpDJ93PAIHc4rHNsrC gYsL8pLckCAcAkrTXZ4BrUdyMF6Kr4U7Sy2VsqnMmE1QtRdvnEuRNTdm14ZLY1sB6bDj hjKQ== 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=rWBUKQdTHLyRHkcWuj84NGtDYVQvG/tlGjYutJW+MHM=; b=eZosgxH92Bt7fVBaeQp6PSmxkrgrbi6lymmfbCf3YyBBISvbKpkKLFE0v4L0ic30+W fgRVXjcMY8X7r4ry53ryXMBRLAx66JrthtVw9WSYwWTDfQrvImWJF20JX7VJjflz6Wv5 pKzhAHqQJpt9+0+FCgRffH92gz7Qp8xz3op/m2Jqb7zqSn0obRDp0focR1Ufjqu/ormD 5p++TkZGK95nh1GhKAFWs9THS5mRaBklzdEyaLYjA+mF4gZN2C1s2kzl/RMfVaF6DT67 JcRuJlqg1zCfV8g9HHYnPolSwNbW6WCXere2FHZB+PuGeM30w7/43jJXrsx/f+yuOC6D Z0eQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kVuOYUXO; 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 e68si3951pfb.101.2018.11.26.03.21.42; Mon, 26 Nov 2018 03:22:03 -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=kVuOYUXO; 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 S1729249AbeKZVwM (ORCPT + 99 others); Mon, 26 Nov 2018 16:52:12 -0500 Received: from mail.kernel.org ([198.145.29.99]:33606 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727234AbeKZVwM (ORCPT ); Mon, 26 Nov 2018 16:52:12 -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 36FA82146F; Mon, 26 Nov 2018 10:58:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543229906; bh=gf3p8gx0argryZOl7G4myxIzduNNAiGSrSKqM091LFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kVuOYUXO3QHqCUfiOkqEyLEedzgKY7K6YcW0+n8eRoYTZPgicqeFeOZt+yEHy8dgz WwF37CbpDSJbVXEaHenPGVN8nyeor9iqMejObZodHcslzlGxeN2W8fYfEpokygC0fw p3HvocdIw9bDwwhTqHTAV3/80VACLq8WhrkH/sEw= 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.9 35/46] media: v4l: event: Add subscription to list before calling "add" operation Date: Mon, 26 Nov 2018 11:51:24 +0100 Message-Id: <20181126105049.415745879@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105045.447291262@linuxfoundation.org> References: <20181126105045.447291262@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.9-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 [Sakari Ailus: Backported to v4.9 stable] Signed-off-by: Sakari Ailus 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 @@ -197,6 +197,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) @@ -228,27 +244,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 */ kfree(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); kfree(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; @@ -283,7 +295,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); @@ -295,14 +306,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);