[libcamera-devel] [PATCH v2 13/17] v4l2: v4l2_camera: Clear pending requests on freeBuffers and streamOff

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sat Jun 20 04:25:07 CEST 2020


Hi Paul,

Thank you for the patch.

On Fri, Jun 19, 2020 at 02:41:19PM +0900, Paul Elder wrote:
> V4L2 allows buffer queueing before streamon while libcamera does not.
> The compatibility layer thus saves these buffers in a pending queue
> until streamon, and then automatically queues them. However, this
> pending queue is not cleared when the buffers are freed, so the
> following sequence of actions will cause a use-after-free:
> 
> 1. queue buffers
> 2. free buffers
>    - buffers from 1. stay in pending queue but have been freed
> 3. queue buffers
> 4. streamon
>    - buffers from 1. are enqueued, then the buffers from 3. are
>      enqueued. Use-after-free segfault when libcamera tries to handle
>      the enqueued buffers from 1.
> 
> Fix this by clearing the pending request queue upon buffers being freed.
> Also clear the pending request queue on streamOff, for correctness.
> 
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> 
> ---
> Changes in v2:
> - also clear pending request queue on streamOff
> - clarify the issue in changelog
> ---
>  src/v4l2/v4l2_camera.cpp | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
> index 99d34b9..301a80e 100644
> --- a/src/v4l2/v4l2_camera.cpp
> +++ b/src/v4l2/v4l2_camera.cpp
> @@ -148,6 +148,7 @@ void V4L2Camera::freeBuffers()
>  	Stream *stream = *camera_->streams().begin();
>  
>  	bufferAllocator_->free(stream);
> +	pendingRequests_.clear();

Wouldn't it be safer to first clear pendingRequests_, as the requests
reference the buffers ? The Request destructor should no access the
buffers, so in practice it should be fine, but inverting the order would
seem less fragile to me.

>  }
>  
>  FileDescriptor V4L2Camera::getBufferFd(unsigned int index)
> @@ -187,7 +188,8 @@ int V4L2Camera::streamOn()
>  
>  int V4L2Camera::streamOff()
>  {
> -	/* \todo Restore buffers to reqbufs state? */
> +	pendingRequests_.clear();
> +

Should this be moved after the isRunning_ check ?

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

>  	if (!isRunning_)
>  		return 0;
>  

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list