diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2018-08-27 11:23:41 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-09-11 09:55:39 -0400 |
commit | ffda0b4c2481b2a0faf634abccb1da0d0ba4eddb (patch) | |
tree | 828fdfd532676a7f0b61b889614fa0d2b617ba56 /drivers/media | |
parent | ca6c163399a9f1913efdbeab654a185b3cde03c4 (diff) | |
download | linux-ffda0b4c2481b2a0faf634abccb1da0d0ba4eddb.tar.gz |
media: v4l2-ctrls: improve media_request_(un)lock_for_update
The request reference count was decreased again once a reference to the
request object was taken. Postpone this until we finished using the object.
In theory I think it is possible that the request_fd can be closed by
the application from another thread. In that case when request_put is
called the whole request would be freed.
It's highly unlikely, but let's just be safe and fix this potential
race condition.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ctrls.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index cc266a4a6e88..95d065d54308 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -3657,10 +3657,9 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, } obj = v4l2_ctrls_find_req_obj(hdl, req, set); - /* Reference to the request held through obj */ - media_request_put(req); if (IS_ERR(obj)) { media_request_unlock_for_update(req); + media_request_put(req); return PTR_ERR(obj); } hdl = container_of(obj, struct v4l2_ctrl_handler, @@ -3670,8 +3669,9 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, ret = try_set_ext_ctrls_common(fh, hdl, cs, set); if (obj) { - media_request_unlock_for_update(obj->req); + media_request_unlock_for_update(req); media_request_object_put(obj); + media_request_put(req); } return ret; |