See attached patch and analysis. Considerations: Nobody has tried to write a exploit for this bug yet, but it does seem like it is exploitable. By default, /proc/acpi/ibm/* can only be written to by root, and thus the bug would only matter if it allows a restricted root user (say, on a SELinux system) to do more damage. HOWEVER, it is entirely possible that either distro scripts, or local admin scripts (running as root) could change the permissions on /proc/acpi/ibm/* to allow for less restricted write access. In that case, the bug can be triggered by non-root users, and thus there is a chance it can be used to escalate priviledges. If you give write access to any local accounts (other than root) to any file under /proc/acpi/ibm, you are at risk of a local root exploit. You have been warned. Please either apply the attached patch (which fixes the security hole for good), or at least make sure /proc/acpi/ibm/* is only writable by root. While at it, please make sure to *disable* CONFIG_THINKPAD_ACPI_BAY and CONFIG_THINKPAD_ACPI_DOCK on your kernel configuration for kernels after 2.6.24, as they can cause a NULL-pointer derreference when the dock or bay is manipulated, and there is a possibility that it could be exploited for priviledge escalation depending on the kernel and local configuration. -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Patch by Michael Buesch <mb@xxxxxxxxx> thinkpad-acpi: Avoid heap buffer overrun Avoid a heap buffer overrun triggered by an integer overflow of the userspace controlled "count" variable. If userspace passes in a "count" of (size_t)-1l, the kmalloc size will overflow to ((size_t)-1l + 2) = 1, so only one byte will be allocated. However, copy_from_user() will attempt to copy 0xFFFFFFFF (or 0xFFFFFFFFFFFFFFFF on 64bit) bytes to the buffer. A possible testcase could look like this: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char **argv) { int fd; char c; if (argc != 2) { printf("Usage: %s /proc/acpi/ibm/filename\n", argv[0]); return 1; } fd = open(argv[1], O_RDWR); if (fd < 0) { printf("Could not open proc file\n"); return 1; } write(fd, &c, (size_t)-1l); } We avoid the integer overrun by putting an arbitrary limit on the count. PAGE_SIZE sounds like a sane limit. Signed-off-by: Michael Buesch <mb@xxxxxxxxx> --- This patch is completely untested due to lack of supported device. The proc file is only writeable by root, so it's probably not exploitable as-is. --- drivers/platform/x86/thinkpad_acpi.c | 2 ++ 1 file changed, 2 insertions(+) --- linux-2.6.orig/drivers/platform/x86/thinkpad_acpi.c +++ linux-2.6/drivers/platform/x86/thinkpad_acpi.c @@ -777,20 +777,22 @@ static int dispatch_procfs_read(char *pa static int dispatch_procfs_write(struct file *file, const char __user *userbuf, unsigned long count, void *data) { struct ibm_struct *ibm = data; char *kernbuf; int ret; if (!ibm || !ibm->write) return -EINVAL; + if (count > PAGE_SIZE - 2) + return -EINVAL; kernbuf = kmalloc(count + 2, GFP_KERNEL); if (!kernbuf) return -ENOMEM; if (copy_from_user(kernbuf, userbuf, count)) { kfree(kernbuf); return -EFAULT; }
------------------------------------------------------------------------------
_______________________________________________ ibm-acpi-devel mailing list ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel