Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fbdev: Add FBINFO_HIDE_SMEM_START flag

DRM drivers really, really, really don't want random userspace to
share buffer behind it's back, bypassing the dma-buf buffer sharing
machanism. For that reason we've ruthlessly rejected any IOCTL
exposing the physical address of any graphics buffer.

Unfortunately fbdev comes with that built-in. We could just set
smem_start to 0, but that means we'd have to hand-roll our own fb_mmap
implementation. For good reasons many drivers do that, but
smem_start/length is still super convenient.

Hence instead just stop the leak in the ioctl, to keep fb mmap working
as-is. A second patch will set this flag for all drm drivers.

Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180822085405.10787-3-daniel.vetter@ffwll.ch

+11
+4
drivers/video/fbdev/core/fbmem.c
··· 1117 1117 if (!lock_fb_info(info)) 1118 1118 return -ENODEV; 1119 1119 fix = info->fix; 1120 + if (info->flags & FBINFO_HIDE_SMEM_START) 1121 + fix.smem_start = 0; 1120 1122 unlock_fb_info(info); 1121 1123 1122 1124 ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0; ··· 1329 1327 if (!lock_fb_info(info)) 1330 1328 return -ENODEV; 1331 1329 fix = info->fix; 1330 + if (info->flags & FBINFO_HIDE_SMEM_START) 1331 + fix.smem_start = 0; 1332 1332 unlock_fb_info(info); 1333 1333 return do_fscreeninfo_to_user(&fix, compat_ptr(arg)); 1334 1334 }
+7
include/linux/fb.h
··· 456 456 * and host endianness. Drivers should not use this flag. 457 457 */ 458 458 #define FBINFO_BE_MATH 0x100000 459 + /* 460 + * Hide smem_start in the FBIOGET_FSCREENINFO IOCTL. This is used by modern DRM 461 + * drivers to stop userspace from trying to share buffers behind the kernel's 462 + * back. Instead dma-buf based buffer sharing should be used. 463 + */ 464 + #define FBINFO_HIDE_SMEM_START 0x200000 465 + 459 466 460 467 struct fb_info { 461 468 atomic_t count;