[libcamera-devel] [PATCH v2 03/17] v4l2: v4l2_camera_proxy: Check for null arg values in main ioctl handler
Paul Elder
paul.elder at ideasonboard.com
Fri Jun 19 07:41:09 CEST 2020
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 at ideasonboard.com>
---
Changes in v2:
- moved !arg check to main ioctl handler, and added a set of supported
ioctls
- use !arg instead of arg == nullptr
---
src/v4l2/v4l2_camera_proxy.cpp | 27 +++++++++++++++++++++++++--
src/v4l2/v4l2_camera_proxy.h | 3 +++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index f06f58d..cff6562 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -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>
@@ -238,7 +239,6 @@ int V4L2CameraProxy::vidioc_enum_fmt(V4L2CameraFile *cf, struct v4l2_fmtdesc *ar
{
LOG(V4L2Compat, Debug) << "Servicing vidioc_enum_fmt fd = " << cf->efd();
-
if (!validateBufferType(arg->type) ||
arg->index >= streamConfig_.formats().pixelformats().size())
return -EINVAL;
@@ -255,7 +255,6 @@ int V4L2CameraProxy::vidioc_g_fmt(V4L2CameraFile *cf, struct v4l2_format *arg)
{
LOG(V4L2Compat, Debug) << "Servicing vidioc_g_fmt fd = " << cf->efd();
-
if (!validateBufferType(arg->type))
return -EINVAL;
@@ -543,8 +542,32 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *cf, int *arg)
return ret;
}
+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 *cf, unsigned long request, void *arg)
{
+ if (supportedIoctls_.find(request) == supportedIoctls_.end()) {
+ errno = ENOTTY;
+ return -1;
+ }
+
+ if (!arg) {
+ errno = EFAULT;
+ return -1;
+ }
+
int ret;
switch (request) {
case VIDIOC_QUERYCAP:
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index 43290ca..dd7e793 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -11,6 +11,7 @@
#include <linux/videodev2.h>
#include <map>
#include <memory>
+#include <set>
#include <sys/mman.h>
#include <sys/types.h>
#include <vector>
@@ -67,6 +68,8 @@ private:
static PixelFormat v4l2ToDrm(uint32_t format);
static uint32_t drmToV4L2(const PixelFormat &format);
+ static std::set<unsigned long> supportedIoctls_;
+
unsigned int refcount_;
unsigned int index_;
--
2.27.0
More information about the libcamera-devel
mailing list