fbdev: Make support for userspace interfaces configurable
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 13 Jun 2023 11:07:13 +0000 (13:07 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 27 Jun 2023 07:58:51 +0000 (09:58 +0200)
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: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230613110953.24176-39-tzimmermann@suse.de
Documentation/gpu/todo.rst
drivers/staging/fbtft/Kconfig
drivers/video/fbdev/Kconfig
drivers/video/fbdev/core/Makefile
drivers/video/fbdev/core/fb_internal.h
drivers/video/fbdev/omap2/omapfb/Kconfig
include/linux/fb.h

index ca1efad8c89c3771fe75ffef5cd4430d6197cdd0..d0f9f87ea515d4b8dc7dc3182576e4f58657912b 100644 (file)
@@ -443,6 +443,19 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
 
 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
 =================
index 4d29e8c1014e0d21cb6167d5390e066c36ee04c0..5dda3c65a38e7ed37312cf4e0a66c49f8023082f 100644 (file)
@@ -2,6 +2,7 @@
 menuconfig FB_TFT
        tristate "Support for small TFT LCD display modules"
        depends on FB && SPI
+       depends on FB_DEVICE
        depends on GPIOLIB || COMPILE_TEST
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
index 6df9bd09454a26b45559bf49168c166cb016d180..cecf15418632d5c740bc6e584add065154139947 100644 (file)
@@ -57,6 +57,16 @@ config FIRMWARE_EDID
          combination with certain motherboards and monitors are known to
          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
        tristate
        depends on FB
@@ -1545,6 +1555,7 @@ config FB_3DFX_I2C
 config FB_VOODOO1
        tristate "3Dfx Voodoo Graphics (sst1) support"
        depends on FB && PCI
+       depends on FB_DEVICE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
@@ -1862,6 +1873,7 @@ config FB_SH_MOBILE_LCDC
        tristate "SuperH Mobile LCDC framebuffer support"
        depends on FB && HAVE_CLK && HAS_IOMEM
        depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
+       depends on FB_DEVICE
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
@@ -1930,6 +1942,7 @@ config FB_SMSCUFX
 config FB_UDL
        tristate "Displaylink USB Framebuffer support"
        depends on FB && USB
+       depends on FB_DEVICE
        select FB_MODE_HELPERS
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
index eea5938f74238df5eeebb660212e034ca27bf53c..9150bafd9e89921ddaa3b363535e70e390dc2b25 100644 (file)
@@ -2,12 +2,13 @@
 obj-$(CONFIG_FB_NOTIFY)           += fb_notify.o
 obj-$(CONFIG_FB)                  += fb.o
 fb-y                              := fb_backlight.o \
-                                     fb_chrdev.o \
                                      fb_info.o \
-                                     fb_procfs.o \
-                                     fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+                                     fbmem.o fbmon.o fbcmap.o \
                                      modedb.o fbcvt.o fb_cmdline.o fb_io_fops.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)
 fb-y                             += fbcon.o bitblit.o softcursor.o
index 0b43c0cd50968b557dd394bdaf527fd0f95d9fa3..4c8d509a002652f45d13ef8e52fdb4df5519d36f 100644 (file)
@@ -3,12 +3,22 @@
 #ifndef _FB_INTERNAL_H
 #define _FB_INTERNAL_H
 
+#include <linux/device.h>
 #include <linux/fb.h>
 #include <linux/mutex.h>
 
 /* fb_devfs.c */
+#if defined(CONFIG_FB_DEVICE)
 int fb_register_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 */
 extern struct class *fb_class;
@@ -19,11 +29,39 @@ struct fb_info *get_fb_info(unsigned int idx);
 void put_fb_info(struct fb_info *fb_info);
 
 /* fb_procfs.c */
+#if defined(CONFIG_FB_DEVICE)
 int fb_init_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 */
+#if defined(CONFIG_FB_DEVICE)
 int fb_device_create(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
index 69f9cb03507ef3c639974c962959f4e8301616de..21069fdb7cc21d64956bc4f8bbe4ce81fe83d484 100644 (file)
@@ -5,9 +5,9 @@ config OMAP2_VRFB
 menuconfig FB_OMAP2
        tristate "OMAP2+ frame buffer support"
        depends on FB
+       depends on FB_DEVICE
        depends on DRM_OMAP = n
        depends on GPIOLIB
-
        select FB_OMAP2_DSS
        select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
        select FB_CFB_FILLRECT
index a7f55edca3733517b76d1b9e6dab592147292324..1d5c13f34b09866415c13637069e53d0262bc965 100644 (file)
@@ -481,7 +481,9 @@ struct fb_info {
 
        const struct fb_ops *fbops;
        struct device *device;          /* This is the parent */
+#if defined(CONFIG_FB_DEVICE)
        struct device *dev;             /* This is this fb device */
+#endif
        int class_flag;                    /* private sysfs flags */
 #ifdef CONFIG_FB_TILEBLITTING
        struct fb_tile_ops *tileops;    /* Tile Blitting */