History

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}

Chris Wilson committed 8 years ago

Commit 70109351 parent 6960e6d3 files · +36 −11Browse files

Unified · Split

3 files
  1. drivers/gpu/drm/drm_fourcc.c +27 −10
  2. drivers/gpu/drm/drm_framebuffer.c +6 −1
  3. include/uapi/drm/drm_fourcc.h +3 −0
drivers/gpu/drm/drm_fourcc.c+27−10
@@ -45,32 +45,49 @@ static char printable_char(int c) · 44 unmodified lines
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+6−1
@@ -112,12 +112,17 @@ int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or, · 111 unmodified lines
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+3−0
@@ -71,6 +71,9 @@ extern "C" { · 70 unmodified lines
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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t