[libcamera-devel] [PATCH] v4l2: v4l2_camera_proxy: Prevent ioctl sign-extensions
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Tue Jul 11 12:56:56 CEST 2023
Hi Kieran
On Tue, Jul 11, 2023 at 11:26:56AM +0100, Kieran Bingham wrote:
> Quoting Kieran Bingham (2023-07-11 10:20:14)
> > Hi Jacopo,
> >
> > On 11/07/2023 10:06, Jacopo Mondi wrote:
> > > Hi Kieran
> > >
> > > On Wed, Jul 05, 2023 at 12:22:48AM +0100, Kieran Bingham via libcamera-devel wrote:
> > >> Handling ioctl's within applications is often wrapped with a helper such
> > >> as xioctl. Unfortunately, there are many instances of xioctl which
> > >> incorrectly handle the correct size of the ioctl request.
> > >>
> > >> This leads to incorrect sign-extension of ioctl's which have bit-31 set,
> > >
> > > I would expect this if the function arguments were signed, but does
> > > sign-extension happens with unsigned arguments as well ?
> >
> > The issue is in the caller - not this function. This patch aims to
> > handle things in the same way the kernel does (which only processes 32
> > bits of the data).
> >
> > For instance, the linux kernel documentation has a sample implementation
> > of xioctl that would cause the fault that this patch fixes:
> >
> > https://www.kernel.org/doc/html/v4.11/media/uapi/v4l/capture.c.html
> >
> > static int xioctl(int fh, int request, void *arg)
Shouldn't this be a long ?
> > {
> > int r;
> >
> > do {
> > r = ioctl(fh, request, arg);
> > } while (-1 == r && EINTR == errno);
> >
> > return r;
> > }
> >
> > If an application uses that xioctl, with the 'int request' and calls
> >
> > if (xioctl(vid_source, VIDIOC_QUERYCAP, &vid_source->cap) < 0) {
> > }
> >
> > The VIDIOC_QUERYCAP (0x80685600) gets sign extended into
> > (0xffffffff80685600) and then doesn't match the parsing in the V4L2
> > adaptation layer.
> >
> >
> > >
> > >> and can cause values to be passed into the libcamera's v4l2 adaptation
> > >> layer which no longer represent the true IOCTL code.
> > >>
> > >> Match the implementation of the Linux kernel and ensure that only 32
> > >> bits of the ioctl request are used by assigning to an unsigned int.
> > >>
> >
> > I'll add:
> >
> > Link: https://github.com/Motion-Project/motion/discussions/1636
> >
> > >> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> > >> ---
> > >> This is a (simpler) rework of the previous patch [0]:
> > >> v4l2: v4l2_camera_proxy: Detect ioctl sign-extensions
> > >>
> > >> [0] https://patchwork.libcamera.org/patch/18311/
> > >>
> > >> src/v4l2/v4l2_camera_proxy.cpp | 12 +++++++++++-
> > >> 1 file changed, 11 insertions(+), 1 deletion(-)
> > >>
> > >> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > >> index 55ff62cdb430..dfb672080219 100644
> > >> --- a/src/v4l2/v4l2_camera_proxy.cpp
> > >> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > >> @@ -778,10 +778,20 @@ const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
> > >> VIDIOC_STREAMOFF,
> > >> };
> > >>
> > >> -int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *arg)
> > >> +int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long longRequest, void *arg)
> > >> {
> > >> MutexLocker locker(proxyMutex_);
> > >>
> > >> + /*
> > >> + * The Linux Kernel only processes 32 bits of an IOCTL.
> > >> + *
> > >> + * Prevent unexpected sign-extensions that could occur if applications
> > >> + * use an unsigned int for the ioctl request, which would sign-extend
>
> Aha, perhaps your comment was here and this should actually read:
>
> "if applications use a signed int for the ioctl request"
>
> I'll s/unsigned int/signed int/
>
Thanks, also this bit was confusing
Anyway, the patch looks good
Reviewed-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
Thanks
j
> --
> Kieran
>
>
> > >> + * to an incorrect value for unsigned longs on 64 bit architectures by
> > >> + * explicitly casting as an unsigned int here.
> > >> + */
> > >> + unsigned int request = longRequest;
> > >> +
> > >> if (!arg && (_IOC_DIR(request) & _IOC_WRITE)) {
> > >> errno = EFAULT;
> > >> return -1;
> > >> --
> > >> 2.34.1
> > >>
More information about the libcamera-devel
mailing list