v4l2: v4l2_camera_proxy: Check for null arg values in main ioctl handler

The ioctl handlers currently don't check if arg is null, so if it ever
is, it will cause a segfault. Check that arg is null and return -EFAULT
in the main vidioc ioctl handler.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Paul Elder 2020-06-16 18:23:43 +09:00
parent 02802aa11f
commit b5d61c86ab
2 changed files with 33 additions and 0 deletions

View file

@ -11,6 +11,7 @@
#include <array>
#include <errno.h>
#include <linux/videodev2.h>
#include <set>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
@ -521,8 +522,37 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)
return ret;
}
const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
VIDIOC_QUERYCAP,
VIDIOC_ENUM_FMT,
VIDIOC_G_FMT,
VIDIOC_S_FMT,
VIDIOC_TRY_FMT,
VIDIOC_REQBUFS,
VIDIOC_QUERYBUF,
VIDIOC_QBUF,
VIDIOC_DQBUF,
VIDIOC_STREAMON,
VIDIOC_STREAMOFF,
};
int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *arg)
{
if (!arg && (_IOC_DIR(request) & _IOC_WRITE)) {
errno = EFAULT;
return -1;
}
if (supportedIoctls_.find(request) == supportedIoctls_.end()) {
errno = ENOTTY;
return -1;
}
if (!arg && (_IOC_DIR(request) & _IOC_READ)) {
errno = EFAULT;
return -1;
}
int ret;
switch (request) {
case VIDIOC_QUERYCAP:

View file

@ -11,6 +11,7 @@
#include <linux/videodev2.h>
#include <map>
#include <memory>
#include <set>
#include <sys/mman.h>
#include <sys/types.h>
#include <vector>
@ -68,6 +69,8 @@ private:
static PixelFormat v4l2ToDrm(uint32_t format);
static uint32_t drmToV4L2(const PixelFormat &format);
static const std::set<unsigned long> supportedIoctls_;
unsigned int refcount_;
unsigned int index_;