aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-09-05 11:31:16 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2018-09-06 03:07:41 -0400
commit70109354fed232dfce8fb2c7cadf635acbe03e19 (patch)
tree4a5332f978526920d708dab36d30393dbbdb7dbd
parent6960e6da9cec3f6638121527c728305827ec12ab (diff)
drm: Reject unknown legacy bpp and depth for drm_mode_addfb ioctl
Since this is handling user provided bpp and depth, we need to sanity check and propagate the EINVAL back rather than assume what the insane client intended and fill the logs with DRM_ERROR. v2: Check both bpp and depth match the builtin pixel format, and introduce a canonical DRM_FORMAT_INVALID to reserve 0 against any future fourcc. v3: Mark up DRM_FORMAT_C8 as being {bpp:8, depth:8} Testcase: igt/kms_addfb_basic/legacy-format Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20180905153116.28924-1-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/drm_fourcc.c37
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c7
-rw-r--r--include/uapi/drm/drm_fourcc.h3
3 files changed, 36 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 35c1e2742c27..be1d6aaef651 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -45,32 +45,49 @@ static char printable_char(int c)
45 */ 45 */
46uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) 46uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
47{ 47{
48 uint32_t fmt; 48 uint32_t fmt = DRM_FORMAT_INVALID;
49 49
50 switch (bpp) { 50 switch (bpp) {
51 case 8: 51 case 8:
52 fmt = DRM_FORMAT_C8; 52 if (depth == 8)
53 fmt = DRM_FORMAT_C8;
53 break; 54 break;
55
54 case 16: 56 case 16:
55 if (depth == 15) 57 switch (depth) {
58 case 15:
56 fmt = DRM_FORMAT_XRGB1555; 59 fmt = DRM_FORMAT_XRGB1555;
57 else 60 break;
61 case 16:
58 fmt = DRM_FORMAT_RGB565; 62 fmt = DRM_FORMAT_RGB565;
63 break;
64 default:
65 break;
66 }
59 break; 67 break;
68
60 case 24: 69 case 24:
61 fmt = DRM_FORMAT_RGB888; 70 if (depth == 24)
71 fmt = DRM_FORMAT_RGB888;
62 break; 72 break;
73
63 case 32: 74 case 32:
64 if (depth == 24) 75 switch (depth) {
76 case 24:
65 fmt = DRM_FORMAT_XRGB8888; 77 fmt = DRM_FORMAT_XRGB8888;
66 else if (depth == 30) 78 break;
79 case 30:
67 fmt = DRM_FORMAT_XRGB2101010; 80 fmt = DRM_FORMAT_XRGB2101010;
68 else 81 break;
82 case 32:
69 fmt = DRM_FORMAT_ARGB8888; 83 fmt = DRM_FORMAT_ARGB8888;
84 break;
85 default:
86 break;
87 }
70 break; 88 break;
89
71 default: 90 default:
72 DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
73 fmt = DRM_FORMAT_XRGB8888;
74 break; 91 break;
75 } 92 }
76 93
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index f863f8a20f8c..c8a7829d73d6 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -112,12 +112,17 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
112 struct drm_mode_fb_cmd2 r = {}; 112 struct drm_mode_fb_cmd2 r = {};
113 int ret; 113 int ret;
114 114
115 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
116 if (r.pixel_format == DRM_FORMAT_INVALID) {
117 DRM_DEBUG("bad {bpp:%d, depth:%d}\n", or->bpp, or->depth);
118 return -EINVAL;
119 }
120
115 /* convert to new format and call new ioctl */ 121 /* convert to new format and call new ioctl */
116 r.fb_id = or->fb_id; 122 r.fb_id = or->fb_id;
117 r.width = or->width; 123 r.width = or->width;
118 r.height = or->height; 124 r.height = or->height;
119 r.pitches[0] = or->pitch; 125 r.pitches[0] = or->pitch;
120 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
121 r.handles[0] = or->handle; 126 r.handles[0] = or->handle;
122 127
123 if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp && 128 if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp &&
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 2ed46e9ae16a..139632b87181 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -71,6 +71,9 @@ extern "C" {
71 71
72#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */ 72#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
73 73
74/* Reserve 0 for the invalid format specifier */
75#define DRM_FORMAT_INVALID 0
76
74/* color index */ 77/* color index */
75#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ 78#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
76 79