Commit 701d2054 authored by Thomas Zimmermann's avatar Thomas Zimmermann

fbdev: Make support for userspace interfaces configurable

Add Kconfig option CONFIG_FB_DEVICE and make the virtual fbdev
device optional. If the new option has not been selected, fbdev
does not create files in devfs, sysfs or procfs.

Most modern Linux systems run a DRM-based graphics stack that uses
the kernel's framebuffer console, but has otherwise deprecated fbdev
support. Yet fbdev userspace interfaces are still present.

The option makes it possible to use the fbdev subsystem as console
implementation without support for userspace. This closes potential
entry points to manipulate kernel or I/O memory via framebuffers. It
also prevents the execution of driver code via ioctl or sysfs, both
of which might allow malicious software to exploit bugs in the fbdev
code.

A small number of fbdev drivers require struct fbinfo.dev to be
initialized, usually for the support of sysfs interface. Make these
drivers depend on FB_DEVICE. They can later be fixed if necessary.

v3:
	* effect -> affect in Kconfig help (Daniel)
v2:
	* set FB_DEVICE default to y (Geert)
	* comment on {get,put}_device() (Sam)
	* Kconfig fixes (Sam)
	* add TODO item about FB_DEVICE dependencies (Sam)
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230613110953.24176-39-tzimmermann@suse.de
parent ff8fbcf6
...@@ -443,6 +443,19 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de> ...@@ -443,6 +443,19 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
Level: Starter Level: Starter
Remove driver dependencies on FB_DEVICE
---------------------------------------
A number of fbdev drivers provide attributes via sysfs and therefore depend
on CONFIG_FB_DEVICE to be selected. Review each driver and attempt to make
any dependencies on CONFIG_FB_DEVICE optional. At the minimum, the respective
code in the driver could be conditionalized via ifdef CONFIG_FB_DEVICE. Not
all drivers might be able to drop CONFIG_FB_DEVICE.
Contact: Thomas Zimmermann <tzimmermann@suse.de>
Level: Starter
Core refactorings Core refactorings
================= =================
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
menuconfig FB_TFT menuconfig FB_TFT
tristate "Support for small TFT LCD display modules" tristate "Support for small TFT LCD display modules"
depends on FB && SPI depends on FB && SPI
depends on FB_DEVICE
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
......
...@@ -57,6 +57,16 @@ config FIRMWARE_EDID ...@@ -57,6 +57,16 @@ config FIRMWARE_EDID
combination with certain motherboards and monitors are known to combination with certain motherboards and monitors are known to
suffer from this problem. suffer from this problem.
config FB_DEVICE
bool "Provide legacy /dev/fb* device"
depends on FB
default y
help
Say Y here if you want the legacy /dev/fb* device file and
interfaces within sysfs anc procfs. It is only required if you
have userspace programs that depend on fbdev for graphics output.
This does not affect the framebuffer console. If unsure, say N.
config FB_DDC config FB_DDC
tristate tristate
depends on FB depends on FB
...@@ -1545,6 +1555,7 @@ config FB_3DFX_I2C ...@@ -1545,6 +1555,7 @@ config FB_3DFX_I2C
config FB_VOODOO1 config FB_VOODOO1
tristate "3Dfx Voodoo Graphics (sst1) support" tristate "3Dfx Voodoo Graphics (sst1) support"
depends on FB && PCI depends on FB && PCI
depends on FB_DEVICE
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
...@@ -1862,6 +1873,7 @@ config FB_SH_MOBILE_LCDC ...@@ -1862,6 +1873,7 @@ config FB_SH_MOBILE_LCDC
tristate "SuperH Mobile LCDC framebuffer support" tristate "SuperH Mobile LCDC framebuffer support"
depends on FB && HAVE_CLK && HAS_IOMEM depends on FB && HAVE_CLK && HAS_IOMEM
depends on SUPERH || ARCH_RENESAS || COMPILE_TEST depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
depends on FB_DEVICE
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
...@@ -1930,6 +1942,7 @@ config FB_SMSCUFX ...@@ -1930,6 +1942,7 @@ config FB_SMSCUFX
config FB_UDL config FB_UDL
tristate "Displaylink USB Framebuffer support" tristate "Displaylink USB Framebuffer support"
depends on FB && USB depends on FB && USB
depends on FB_DEVICE
select FB_MODE_HELPERS select FB_MODE_HELPERS
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
......
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
obj-$(CONFIG_FB_NOTIFY) += fb_notify.o obj-$(CONFIG_FB_NOTIFY) += fb_notify.o
obj-$(CONFIG_FB) += fb.o obj-$(CONFIG_FB) += fb.o
fb-y := fb_backlight.o \ fb-y := fb_backlight.o \
fb_chrdev.o \
fb_info.o \ fb_info.o \
fb_procfs.o \ fbmem.o fbmon.o fbcmap.o \
fbmem.o fbmon.o fbcmap.o fbsysfs.o \
modedb.o fbcvt.o fb_cmdline.o fb_io_fops.o modedb.o fbcvt.o fb_cmdline.o fb_io_fops.o
fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
fb-$(CONFIG_FB_DEVICE) += fb_chrdev.o \
fb_procfs.o \
fbsysfs.o
ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y) ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y)
fb-y += fbcon.o bitblit.o softcursor.o fb-y += fbcon.o bitblit.o softcursor.o
......
...@@ -3,12 +3,22 @@ ...@@ -3,12 +3,22 @@
#ifndef _FB_INTERNAL_H #ifndef _FB_INTERNAL_H
#define _FB_INTERNAL_H #define _FB_INTERNAL_H
#include <linux/device.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/mutex.h> #include <linux/mutex.h>
/* fb_devfs.c */ /* fb_devfs.c */
#if defined(CONFIG_FB_DEVICE)
int fb_register_chrdev(void); int fb_register_chrdev(void);
void fb_unregister_chrdev(void); void fb_unregister_chrdev(void);
#else
static inline int fb_register_chrdev(void)
{
return 0;
}
static inline void fb_unregister_chrdev(void)
{ }
#endif
/* fbmem.c */ /* fbmem.c */
extern struct class *fb_class; extern struct class *fb_class;
...@@ -19,11 +29,39 @@ struct fb_info *get_fb_info(unsigned int idx); ...@@ -19,11 +29,39 @@ struct fb_info *get_fb_info(unsigned int idx);
void put_fb_info(struct fb_info *fb_info); void put_fb_info(struct fb_info *fb_info);
/* fb_procfs.c */ /* fb_procfs.c */
#if defined(CONFIG_FB_DEVICE)
int fb_init_procfs(void); int fb_init_procfs(void);
void fb_cleanup_procfs(void); void fb_cleanup_procfs(void);
#else
static inline int fb_init_procfs(void)
{
return 0;
}
static inline void fb_cleanup_procfs(void)
{ }
#endif
/* fbsysfs.c */ /* fbsysfs.c */
#if defined(CONFIG_FB_DEVICE)
int fb_device_create(struct fb_info *fb_info); int fb_device_create(struct fb_info *fb_info);
void fb_device_destroy(struct fb_info *fb_info); void fb_device_destroy(struct fb_info *fb_info);
#else
static inline int fb_device_create(struct fb_info *fb_info)
{
/*
* Acquire a reference on the parent device to avoid
* unplug operations behind our back. With the fbdev
* device enabled, this is performed within register_device().
*/
get_device(fb_info->device);
return 0;
}
static inline void fb_device_destroy(struct fb_info *fb_info)
{
/* Undo the get_device() from fb_device_create() */
put_device(fb_info->device);
}
#endif
#endif #endif
...@@ -5,9 +5,9 @@ config OMAP2_VRFB ...@@ -5,9 +5,9 @@ config OMAP2_VRFB
menuconfig FB_OMAP2 menuconfig FB_OMAP2
tristate "OMAP2+ frame buffer support" tristate "OMAP2+ frame buffer support"
depends on FB depends on FB
depends on FB_DEVICE
depends on DRM_OMAP = n depends on DRM_OMAP = n
depends on GPIOLIB depends on GPIOLIB
select FB_OMAP2_DSS select FB_OMAP2_DSS
select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
......
...@@ -481,7 +481,9 @@ struct fb_info { ...@@ -481,7 +481,9 @@ struct fb_info {
const struct fb_ops *fbops; const struct fb_ops *fbops;
struct device *device; /* This is the parent */ struct device *device; /* This is the parent */
#if defined(CONFIG_FB_DEVICE)
struct device *dev; /* This is this fb device */ struct device *dev; /* This is this fb device */
#endif
int class_flag; /* private sysfs flags */ int class_flag; /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING #ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */ struct fb_tile_ops *tileops; /* Tile Blitting */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment