Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4611403pxj; Wed, 12 May 2021 09:13:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzXODefCtju8ySsm0dbUpLzR9azbe2R7/R4zGZs5fbZuWALY3De97/gzdLatpbTV23Sk0+Z X-Received: by 2002:a17:906:3bca:: with SMTP id v10mr6894786ejf.121.1620835980905; Wed, 12 May 2021 09:13:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620835980; cv=none; d=google.com; s=arc-20160816; b=k6wLrTCQF0hT4Dy3bSNG4PMFqdugfpNh+Pb/KMn9/Dp10eEx9xNmx851DoUasyZyg6 gqq0dbrJep53CrqmnfBjSDi6gdBMCfXaADD+yN/mvHkc+jbDoZ7PFrw/Bi8B9W7sHJ+I ZWauWFdDeKhigQvTWo393AjWNDu/IkfUo06yEliAlYmBpT+l03E/ce2Sz8mfetVXN9u2 GfKDOGcAS8oXUXVG5VPxaeMnFOyS0LaPA0OZT0omLoqu9rjQJmjlWDXS3gwq7eeXA/Y0 tyRfqo4wMjX/pzBCvQUMIpj6BKZe+EgfMJLxCDKSL9TfVnH/gFGn7LHFCkqeG1fuuOKk UROw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+nFWNtqYg15Yg3lE3dJEKEOen8whuLQ2rFws1OTphUA=; b=vPPjpneJsLzx/4iuNRB7lJPCH2+QW8Fm5yhGpa2VjRmxWb7adJXoYfAFSNb6P7VSk6 CKAbGtBEDTNHu0aygKrDOX9QxXzWvNqpuu91RC/46P22DOQrlQYzh4Xhis0ybqNt2qb/ rjcBK0p0cTAHs6CD4/bkqHwfAZEPAVHwG011VZypjBj1BYrXSFXAwZ4luzkLngsXuvNe 4vJTpeiWiWCgCxT3fTntkmrBoGZBGX/ZcYNEc+oh6PyvZEOPG6c5VuX2Tqnv4eHbL91p 2BpxBxDfNilNd/9wh859KOP5iZzDJJeZBw2fVkf8LlkS+b9na1GdPnpPURNpwZF6HaLM 2fvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=rnencMB4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dy22si123249edb.301.2021.05.12.09.12.17; Wed, 12 May 2021 09:13:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=rnencMB4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239544AbhELQJ6 (ORCPT + 99 others); Wed, 12 May 2021 12:09:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:40900 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233570AbhELP3L (ORCPT ); Wed, 12 May 2021 11:29:11 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id F11316193F; Wed, 12 May 2021 15:15:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620832525; bh=VWFmY4z/NlBwoDH/EhdZqcBO8Ar056yKz4fg6DAKE1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rnencMB4JUGm/LuiqCgA2cjg9nbuOc70zcS3LRUi8JuhNCt06YVQVYoGdfudAnbP1 829MWGITT5kODGz23FJkoLaytz/BzedvGH1/Ib2obJMma1sQtoWaoBz/VAd+KQe4Eo xCuz7QYi9JzYvZO39b9cH7YnsFD3vBtF7+2O2SNA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans Verkuil , John Cox , Mauro Carvalho Chehab , Sasha Levin Subject: [PATCH 5.10 315/530] media: v4l2-ctrls.c: fix race condition in hdl->requests list Date: Wed, 12 May 2021 16:47:05 +0200 Message-Id: <20210512144830.162657196@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144819.664462530@linuxfoundation.org> References: <20210512144819.664462530@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hans Verkuil [ Upstream commit be7e8af98f3af729aa9f08b1053f9533a5cceb91 ] When a request is re-inited it will release all control handler objects that are still in the request. It does that by unbinding and putting all those objects. When the object is unbound the obj->req pointer is set to NULL, and the object's unbind op is called. When the object it put the object's release op is called to free the memory. For a request object that contains a control handler that means that v4l2_ctrl_handler_free() is called in the release op. A control handler used in a request has a pointer to the main control handler that is created by the driver and contains the current state of all controls. If the device is unbound (due to rmmod or a forced unbind), then that main handler is freed, again by calling v4l2_ctrl_handler_free(), and any outstanding request objects that refer to that main handler have to be unbound and put as well. It does that by this test: if (!hdl->req_obj.req && !list_empty(&hdl->requests)) { I.e. the handler has no pointer to a request, so is the main handler, and one or more request objects refer to this main handler. However, this test is wrong since hdl->req_obj.req is actually NULL when re-initing a request (the object unbind will set req to NULL), and the only reason this seemingly worked is that the requests list is typically empty since the request's unbind op will remove the handler from the requests list. But if another thread is at the same time adding a new control to a request, then there is a race condition where one thread is removing a control handler object from the requests list and another thread is adding one. The result is that hdl->requests is no longer empty and the code thinks that a main handler is being freed instead of a control handler that is part of a request. There are two bugs here: first the test for hdl->req_obj.req: this should be hdl->req_obj.ops since only the main control handler will have a NULL pointer there. The second is that adding or deleting request objects from the requests list of the main handler isn't protected by taking the main handler's lock. Signed-off-by: Hans Verkuil Reported-by: John Cox Fixes: 6fa6f831f095 ("media: v4l2-ctrls: add core request support") Tested-by: John Cox Reported-by: John Cox Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/v4l2-core/v4l2-ctrls.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 3d8c54b826e9..41f8410d08d6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -2356,7 +2356,15 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) if (hdl == NULL || hdl->buckets == NULL) return; - if (!hdl->req_obj.req && !list_empty(&hdl->requests)) { + /* + * If the main handler is freed and it is used by handler objects in + * outstanding requests, then unbind and put those objects before + * freeing the main handler. + * + * The main handler can be identified by having a NULL ops pointer in + * the request object. + */ + if (!hdl->req_obj.ops && !list_empty(&hdl->requests)) { struct v4l2_ctrl_handler *req, *next_req; list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { @@ -3402,8 +3410,8 @@ static void v4l2_ctrl_request_unbind(struct media_request_object *obj) container_of(obj, struct v4l2_ctrl_handler, req_obj); struct v4l2_ctrl_handler *main_hdl = obj->priv; - list_del_init(&hdl->requests); mutex_lock(main_hdl->lock); + list_del_init(&hdl->requests); if (hdl->request_is_queued) { list_del_init(&hdl->requests_queued); hdl->request_is_queued = false; @@ -3462,8 +3470,11 @@ static int v4l2_ctrl_request_bind(struct media_request *req, if (!ret) { ret = media_request_object_bind(req, &req_ops, from, false, &hdl->req_obj); - if (!ret) + if (!ret) { + mutex_lock(from->lock); list_add_tail(&hdl->requests, &from->requests); + mutex_unlock(from->lock); + } } return ret; } -- 2.30.2