From patchwork Thu Apr 5 17:52:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?R=C3=A9mi_Denis-Courmont?= X-Patchwork-Id: 10592 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1SFqs6-0000hG-Hy for patchwork@linuxtv.org; Thu, 05 Apr 2012 19:53:22 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-3) with esmtp for id 1SFqs5-00062J-FI; Thu, 05 Apr 2012 19:53:22 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753324Ab2DERw5 (ORCPT ); Thu, 5 Apr 2012 13:52:57 -0400 Received: from oyp.chewa.net ([91.121.6.101]:46481 "EHLO oyp.chewa.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753135Ab2DERw4 (ORCPT ); Thu, 5 Apr 2012 13:52:56 -0400 Received: from basile.remlab.net (ip6-localhost [IPv6:::1]) by oyp.chewa.net (Postfix) with SMTP id 0CDBE200EE; Thu, 5 Apr 2012 19:52:44 +0200 (CEST) Received: by basile.remlab.net (sSMTP sendmail emulation); Thu, 05 Apr 2012 20:52:51 +0300 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= To: mchehab@infradead.org, linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC] [PATCH] v4l2: use unsigned rather than enums in ioctl() structs Date: Thu, 5 Apr 2012 20:52:51 +0300 Message-Id: <1333648371-24812-1-git-send-email-remi@remlab.net> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.4.5.173914 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' HTML_00_01 0.05, HTML_00_10 0.05, BODY_SIZE_6000_6999 0, BODY_SIZE_7000_LESS 0, CT_TEXT_PLAIN_UTF8_CAPS 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __CT 0, __CTE 0, __CT_TEXT_PLAIN 0, __DATE_TZ_RU 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' With an enumeration, the compiler assumes that the integer value is one allowed by the underlying enumeration type. With optimization enabled this can result in byte code that is unable to cope with other values. For instance, GCC can compile a switch() block using a "jump table" to avoid repetitive conditional branching. This can be a problem both from user to kernel and kernel to user. * Evil user space can pass error values to the kernel via system calls. There are no sane ways to protect the kernel: the compiler may optimize away range checks if it deems that all legitimate values are within the range. * The kernel can break the user space binary interface whenever a new value is added to an existing enumeration. A newer kernel can then return an enumerated value that was not allowed by older kernel headers against which the user program was compiled. In principles, V4L2 user space needs to be recompiled whenever videodev2.h has updated enums... (This an obvious problem with V4L2_QUERYCTRL.) Fortunately, the Linux ABI disables short-enums on all platforms. Even the Linux variant of the ARM AAPCS contradicts the standard ARM AAPCS in doing so. Signed-off-by: RĂ©mi Denis-Courmont --- include/linux/videodev2.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index c9c9a46..df3b8f0 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -292,10 +292,10 @@ struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; - enum v4l2_field field; + unsigned field; __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; - enum v4l2_colorspace colorspace; + unsigned colorspace; __u32 priv; /* private data, depends on pixelformat */ }; @@ -432,7 +432,7 @@ struct v4l2_pix_format { */ struct v4l2_fmtdesc { __u32 index; /* Format number */ - enum v4l2_buf_type type; /* buffer type */ + unsigned type; /* buffer type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ @@ -573,8 +573,8 @@ struct v4l2_jpegcompression { */ struct v4l2_requestbuffers { __u32 count; - enum v4l2_buf_type type; - enum v4l2_memory memory; + unsigned type; + unsigned memory; __u32 reserved[2]; }; @@ -636,16 +636,16 @@ struct v4l2_plane { */ struct v4l2_buffer { __u32 index; - enum v4l2_buf_type type; + unsigned type; __u32 bytesused; __u32 flags; - enum v4l2_field field; + unsigned field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ - enum v4l2_memory memory; + unsigned memory; union { __u32 offset; unsigned long userptr; @@ -708,7 +708,7 @@ struct v4l2_clip { struct v4l2_window { struct v4l2_rect w; - enum v4l2_field field; + unsigned field; __u32 chromakey; struct v4l2_clip __user *clips; __u32 clipcount; @@ -745,14 +745,14 @@ struct v4l2_outputparm { * I N P U T I M A G E C R O P P I N G */ struct v4l2_cropcap { - enum v4l2_buf_type type; + unsigned type; struct v4l2_rect bounds; struct v4l2_rect defrect; struct v4l2_fract pixelaspect; }; struct v4l2_crop { - enum v4l2_buf_type type; + unsigned type; struct v4l2_rect c; }; @@ -1156,7 +1156,7 @@ enum v4l2_ctrl_type { /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ struct v4l2_queryctrl { __u32 id; - enum v4l2_ctrl_type type; + unsigned type; __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; @@ -1788,7 +1788,7 @@ enum v4l2_jpeg_chroma_subsampling { struct v4l2_tuner { __u32 index; __u8 name[32]; - enum v4l2_tuner_type type; + unsigned type; __u32 capability; __u32 rangelow; __u32 rangehigh; @@ -1838,14 +1838,14 @@ struct v4l2_modulator { struct v4l2_frequency { __u32 tuner; - enum v4l2_tuner_type type; + unsigned type; __u32 frequency; __u32 reserved[8]; }; struct v4l2_hw_freq_seek { __u32 tuner; - enum v4l2_tuner_type type; + unsigned type; __u32 seek_upward; __u32 wrap_around; __u32 spacing; @@ -2056,7 +2056,7 @@ struct v4l2_sliced_vbi_cap { (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; - enum v4l2_buf_type type; + unsigned type; __u32 reserved[3]; /* must be 0 */ }; @@ -2146,8 +2146,8 @@ struct v4l2_pix_format_mplane { __u32 width; __u32 height; __u32 pixelformat; - enum v4l2_field field; - enum v4l2_colorspace colorspace; + unsigned field; + unsigned colorspace; struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; __u8 num_planes; @@ -2165,7 +2165,7 @@ struct v4l2_pix_format_mplane { * @raw_data: placeholder for future extensions and custom formats */ struct v4l2_format { - enum v4l2_buf_type type; + unsigned type; union { struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ @@ -2179,7 +2179,7 @@ struct v4l2_format { /* Stream type-dependent parameters */ struct v4l2_streamparm { - enum v4l2_buf_type type; + unsigned type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; @@ -2299,7 +2299,7 @@ struct v4l2_dbg_chip_ident { struct v4l2_create_buffers { __u32 index; __u32 count; - enum v4l2_memory memory; + unsigned memory; struct v4l2_format format; __u32 reserved[8]; };