From c6ed6dad5cfb76d72d8f9accba9b9f8d572c518c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 15 Nov 2017 17:49:13 +0200 Subject: [PATCH] drm/uapi: Validate the mode flags/type MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Currently userspace is allowed to feed in any king of garbage in the high bits of the mode flags/type, as are drivers when probing modes. Reject any mode with bogus flags/type. Hopefully this won't break any current userspace... v2: Split the type and flags checks to separates ifs (Chris) Cc: Chris Wilson Cc: Jose Abreu Cc: Adam Jackson Cc: Keith Packard Signed-off-by: Ville Syrjälä Reviewed-by: Adam Jackson Link: https://patchwork.freedesktop.org/patch/msgid/20171115154913.23827-1-ville.syrjala@linux.intel.com Reviewed-by: Alex Deucher --- drivers/gpu/drm/drm_modes.c | 6 ++++++ include/uapi/drm/drm_mode.h | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 1a72883b836e..34b5123ebfc0 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1036,6 +1036,12 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode) { + if (mode->type & ~DRM_MODE_TYPE_ALL) + return MODE_BAD; + + if (mode->flags & ~DRM_MODE_FLAG_ALL) + return MODE_BAD; + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX) return MODE_BAD; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 5597a87154e5..004db470b477 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -46,6 +46,14 @@ extern "C" { #define DRM_MODE_TYPE_USERDEF (1<<5) #define DRM_MODE_TYPE_DRIVER (1<<6) +#define DRM_MODE_TYPE_ALL (DRM_MODE_TYPE_BUILTIN | \ + DRM_MODE_TYPE_CLOCK_C | \ + DRM_MODE_TYPE_CRTC_C | \ + DRM_MODE_TYPE_PREFERRED | \ + DRM_MODE_TYPE_DEFAULT | \ + DRM_MODE_TYPE_USERDEF | \ + DRM_MODE_TYPE_DRIVER) + /* Video mode flags */ /* bit compatible with the xrandr RR_ definitions (bits 0-13) * @@ -99,6 +107,22 @@ extern "C" { #define DRM_MODE_FLAG_PIC_AR_16_9 \ (DRM_MODE_PICTURE_ASPECT_16_9<<19) +#define DRM_MODE_FLAG_ALL (DRM_MODE_FLAG_PHSYNC | \ + DRM_MODE_FLAG_NHSYNC | \ + DRM_MODE_FLAG_PVSYNC | \ + DRM_MODE_FLAG_NVSYNC | \ + DRM_MODE_FLAG_INTERLACE | \ + DRM_MODE_FLAG_DBLSCAN | \ + DRM_MODE_FLAG_CSYNC | \ + DRM_MODE_FLAG_PCSYNC | \ + DRM_MODE_FLAG_NCSYNC | \ + DRM_MODE_FLAG_HSKEW | \ + DRM_MODE_FLAG_BCAST | \ + DRM_MODE_FLAG_PIXMUX | \ + DRM_MODE_FLAG_DBLCLK | \ + DRM_MODE_FLAG_CLKDIV2 | \ + DRM_MODE_FLAG_3D_MASK) + /* DPMS flags */ /* bit compatible with the xorg definitions. */ #define DRM_MODE_DPMS_ON 0 -- 2.30.2