From: Don Howard <dhoward@redhat.com> Date: Mon, 19 Jul 2010 21:05:31 -0400 Subject: [acpi] thinkpad-acpi: lock down video output state access Message-id: <alpine.LRH.2.00.1007190855250.7792@notfadeaway.remotee.org> Patchwork-id: 26951 O-Subject: [RHEL5 patch] thinkpad-acip: lock down video output state access Bugzilla: 607037 RH-Acked-by: Danny Feng <dfeng@redhat.com> RH-Acked-by: Jarod Wilson <jarod@redhat.com> Backport of upstream commit b525c06cdbd8a3963f0173ccd23f9147d4c384b5: Author: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Date: Thu Feb 25 22:22:22 2010 -0300 thinkpad-acpi: lock down video output state access Given the right combination of ThinkPad and X.org, just reading the video output control state is enough to hard-crash X.org. Until the day I somehow find out a model or BIOS cut date to not provide this feature to ThinkPads that can do video switching through X RandR, change permissions so that only processes with CAP_SYS_ADMIN can access any sort of video output control state. This bug could be considered a local DoS I suppose, as it allows any non-privledged local user to cause some versions of X.org to hard-crash some ThinkPads. Reported-by: Jidanni <jidanni@jidanni.org> Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: stable@kernel.org I could not find a thinkpad in beaker that exibites the crash described, but I did verify that the patch correctly changes the default access to /proc/acpi/ibm/video with my local thinkpad. Fixes bz607037. Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index 8b3fd82..063db49 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -182,6 +182,10 @@ LCD, CRT or DVI (if available). The following commands are available: echo expand_toggle > /proc/acpi/ibm/video echo video_switch > /proc/acpi/ibm/video +NOTE: Access to this feature is restricted to processes owning the +CAP_SYS_ADMIN capability for safety reasons, as it can interact badly +enough with some versions of X.org to crash it. + Each video output device can be enabled or disabled individually. Reading /proc/acpi/ibm/video shows the status of each device. diff --git a/drivers/acpi/thinkpad_acpi.c b/drivers/acpi/thinkpad_acpi.c index a1bf850..c25ddeb 100644 --- a/drivers/acpi/thinkpad_acpi.c +++ b/drivers/acpi/thinkpad_acpi.c @@ -207,6 +207,7 @@ struct ibm_init_struct { char param[32]; int (*init) (struct ibm_init_struct *); + mode_t base_procfs_mode; struct ibm_struct *data; }; @@ -2993,6 +2994,10 @@ static int video_read(char *p) return len; } + /* Even reads can crash X.org, so... */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + status = video_outputsw_get(); if (status < 0) return status; @@ -3026,6 +3031,10 @@ static int video_write(char *buf) if (video_supported == TPACPI_VIDEO_NONE) return -ENODEV; + /* Even reads can crash X.org, let alone writes... */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + enable = 0; disable = 0; @@ -5701,8 +5710,15 @@ static int __init ibm_init(struct ibm_init_struct *iibm) "%s installed\n", ibm->name); if (ibm->read) { + mode_t mode = iibm->base_procfs_mode; + + if (!mode) + mode = S_IRUGO; + if (ibm->write) + mode |= S_IWUSR; + entry = create_proc_entry(ibm->name, - S_IFREG | S_IRUGO | S_IWUSR, + mode, proc_dir); if (!entry) { printk(TPACPI_ERR "unable to create proc entry %s\n", @@ -5844,6 +5860,7 @@ static struct ibm_init_struct ibms_init[] __initdata = { #ifdef CONFIG_THINKPAD_ACPI_VIDEO { .init = video_init, + .base_procfs_mode = S_IRUSR, .data = &video_driver_data, }, #endif