Skip to content

Commit 7010935

Browse files
committed
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
1 parent 6960e6d commit 7010935

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

drivers/gpu/drm/drm_fourcc.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,49 @@ static char printable_char(int c)
4545
*/
4646
uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
4747
{
48-
uint32_t fmt;
48+
uint32_t fmt = DRM_FORMAT_INVALID;
4949

5050
switch (bpp) {
5151
case 8:
52-
fmt = DRM_FORMAT_C8;
52+
if (depth == 8)
53+
fmt = DRM_FORMAT_C8;
5354
break;
55+
5456
case 16:
55-
if (depth == 15)
57+
switch (depth) {
58+
case 15:
5659
fmt = DRM_FORMAT_XRGB1555;
57-
else
60+
break;
61+
case 16:
5862
fmt = DRM_FORMAT_RGB565;
63+
break;
64+
default:
65+
break;
66+
}
5967
break;
68+
6069
case 24:
61-
fmt = DRM_FORMAT_RGB888;
70+
if (depth == 24)
71+
fmt = DRM_FORMAT_RGB888;
6272
break;
73+
6374
case 32:
64-
if (depth == 24)
75+
switch (depth) {
76+
case 24:
6577
fmt = DRM_FORMAT_XRGB8888;
66-
else if (depth == 30)
78+
break;
79+
case 30:
6780
fmt = DRM_FORMAT_XRGB2101010;
68-
else
81+
break;
82+
case 32:
6983
fmt = DRM_FORMAT_ARGB8888;
84+
break;
85+
default:
86+
break;
87+
}
7088
break;
89+
7190
default:
72-
DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
73-
fmt = DRM_FORMAT_XRGB8888;
7491
break;
7592
}
7693

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,17 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
112112
struct drm_mode_fb_cmd2 r = {};
113113
int ret;
114114

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+
115121
/* convert to new format and call new ioctl */
116122
r.fb_id = or->fb_id;
117123
r.width = or->width;
118124
r.height = or->height;
119125
r.pitches[0] = or->pitch;
120-
r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
121126
r.handles[0] = or->handle;
122127

123128
if (dev->mode_config.quirk_addfb_prefer_xbgr_30bpp &&

include/uapi/drm/drm_fourcc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ extern "C" {
7171

7272
#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
7373

74+
/* Reserve 0 for the invalid format specifier */
75+
#define DRM_FORMAT_INVALID 0
76+
7477
/* color index */
7578
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */
7679

0 commit comments

Comments
 (0)