• H
    media: v4l2-ctrls: fix reference to freed memory · ac34b79d
    Hans Verkuil 提交于
    When controls are used together with the Request API, then for
    each request a v4l2_ctrl_handler struct is allocated. This contains
    the controls that can be set in a request. If a control is *not* set in
    the request, then the value used in the most recent previous request
    must be used, or the current value if it is not found in any outstanding
    requests.
    
    The framework tried to find such a previous request and it would set
    the 'req' pointer in struct v4l2_ctrl_ref to the v4l2_ctrl_ref of the
    control in such a previous request. So far, so good. However, when that
    previous request was applied to the hardware, returned to userspace, and
    then userspace would re-init or free that request, any 'ref' pointer in
    still-queued requests would suddenly point to freed memory.
    
    This was not noticed before since the drivers that use this expected
    that each request would always have the controls set, so there was
    never any need to find a control in older requests. This requirement
    was relaxed, and now this bug surfaced.
    
    It was also made worse by changeset
    2fae4d6a ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req")
    which increased the chance of this happening.
    
    The use of the 'req' pointer in v4l2_ctrl_ref was very fragile, so
    drop this entirely. Instead add a valid_p_req bool to indicate that
    p_req contains a valid value for this control. And if it is false,
    then just use the current value of the control.
    
    Note that VIDIOC_G_EXT_CTRLS will always return -EACCES when attempting
    to get a control from a request until the request is completed. And in
    that case, all controls in the request will have the control value set
    (i.e. valid_p_req is true). This means that the whole 'find the most
    recent previous request containing a control' idea is pointless, and
    the code can be simplified considerably.
    
    The v4l2_g_ext_ctrls_common() function was refactored a bit to make
    it more understandable. It also avoids updating volatile controls
    in a completed request since that was already done when the request
    was completed.
    Signed-off-by: NHans Verkuil <hverkuil-cisco@xs4all.nl>
    Fixes: 2fae4d6a ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req")
    Fixes: 6fa6f831 ("media: v4l2-ctrls: add core request support")
    Cc: <stable@vger.kernel.org>      # for v5.9 and up
    Tested-by: NAlexandre Courbot <acourbot@chromium.org>
    Signed-off-by: NMauro Carvalho Chehab <mchehab+huawei@kernel.org>
    ac34b79d
v4l2-ctrls.c 147.1 KB