Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5647496imu; Mon, 26 Nov 2018 03:29:56 -0800 (PST) X-Google-Smtp-Source: AFSGD/VHXx5At0NeBDA3ujEx3x7I+FSodJbNd3avb1CKKSMTQysBxvxb6Au2cjhg7W0e9bh8W7KL X-Received: by 2002:a17:902:20c6:: with SMTP id v6mr26859847plg.156.1543231796095; Mon, 26 Nov 2018 03:29:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543231796; cv=none; d=google.com; s=arc-20160816; b=opODYlfynRKARVfyXOe/jfUFm4VGVej2U2qNcUj5YKD/30EA+KphpZgqK9yy2nzTRg H5gxMMiSfNZrPcuH0VWwbbZjA6+gjaQDdXxbb91JaXoJ2/t5UkTgRfC223ZsR8itGjxl XmyTcn7X+Xs8Qk7KfjQ8n/qqdTQLNCAMLg+yhE0FDcIgzLX4RAs471j89mL9NuJzWm90 d5m6FT9/qjVpvczkD9b0HAElGCQtKmKNT4OF9J+s01kk8c9Jpcz1dj2y3rvam8l42GX9 7L5F06Al/2HaL7Bs9ZVG0qisEWynj3yUDvdAWl8APwavqDjw0ioQZhsIoRZgwQZOqPbI e1gw== 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=C/mL85+t6l6dlpXXSJQcXXqPTTZOHQS6p8mMwRb469c=; b=Cax27ZP693Bn6AjaDGbCT1thIwEZv+d4JcRyAmzQtSRiBJxrLmQjJsEqSqvidH+gqq li65LwxlI8n3BsV0vj0bZWvpdbaZ3Lly1O6cDLx1h05rBU3AOpymctX9crXtEfvuUJZA Jg710CwFUb8zozJ0HByXQrmtJmNFatvMilV8XVDdayENwOwQ6bU4gL8IBFkwQaHe7NWc 2EM4RlL9YfPdKXU0xDPqCuRwHveZZ6XG4AoBdD4NkDdOFkgm0oiXLxoumHLYgubTvQ+C tM+E6aBLjHklNtcaeSGra4jsIv5NxFkR+MW4QHPIKlqcfBvZNfZJJkNt0Hsq9fTdZcj+ grlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=uvJU6rA1; 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 e2si15406pgs.94.2018.11.26.03.29.16; Mon, 26 Nov 2018 03:29:56 -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=uvJU6rA1; 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 S1726544AbeKZVqi (ORCPT + 99 others); Mon, 26 Nov 2018 16:46:38 -0500 Received: from mail.kernel.org ([198.145.29.99]:54516 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726524AbeKZVqi (ORCPT ); Mon, 26 Nov 2018 16:46:38 -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 BAE362147D; Mon, 26 Nov 2018 10:52:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543229574; bh=GFoeAVCUfxg53TAUXp5wkMKNguHhavjykJNTGHPw+tg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uvJU6rA1tq0LKU4j1+ij2gv6Bes9n+H23zB9qGpOzQoiHLU+Zd6f+BF24RHqdTw5t AbPdjc+wDGvdRLf0lj/37meIJwXLODsEEkDViM9mpcY61dbq0W4H6/Z1iW2efhZ8l5 ujRzqy8XqLuC4J0nGBlDA5RC/gz66eIGQdjsv1Xg= 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 3.18 15/24] media: v4l: event: Add subscription to list before calling "add" operation Date: Mon, 26 Nov 2018 11:51:09 +0100 Message-Id: <20181126105031.969917516@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181126105029.790599475@linuxfoundation.org> References: <20181126105029.790599475@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 3.18-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 @@ -194,6 +194,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 */ 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; @@ -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);