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

drivers/char/hpet.c: allow user controlled mmap for user processes

The CONFIG_HPET_MMAP Kconfig option exposes the memory map of the HPET
registers to userspace. The Kconfig help points out that in some cases
this can be a security risk as some systems may erroneously configure the
map such that additional data is exposed to userspace.

This is a problem for distributions -- some users want the MMAP
functionality but it comes with a significant security risk. In an effort
to mitigate this risk, and due to the low number of users of the MMAP
functionality, I've introduced a kernel parameter, hpet_mmap_enable, that
is required in order to actually have the HPET MMAP exposed.

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Acked-by: Matt Wilson <msw@amazon.com>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Prarit Bhargava and committed by
Linus Torvalds
3d035f58 72403b4a

+35 -6
+3
Documentation/kernel-parameters.txt
··· 1070 1070 VIA, nVidia) 1071 1071 verbose: show contents of HPET registers during setup 1072 1072 1073 + hpet_mmap= [X86, HPET_MMAP] Allow userspace to mmap HPET 1074 + registers. Default set by CONFIG_HPET_MMAP_DEFAULT. 1075 + 1073 1076 hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot. 1074 1077 hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages. 1075 1078 On x86-64 and powerpc, this option can be specified
+8 -2
drivers/char/Kconfig
··· 522 522 If you say Y here, user applications will be able to mmap 523 523 the HPET registers. 524 524 525 + config HPET_MMAP_DEFAULT 526 + bool "Enable HPET MMAP access by default" 527 + default y 528 + depends on HPET_MMAP 529 + help 525 530 In some hardware implementations, the page containing HPET 526 531 registers may also contain other things that shouldn't be 527 - exposed to the user. If this applies to your hardware, 528 - say N here. 532 + exposed to the user. This option selects the default (if 533 + kernel parameter hpet_mmap is not set) user access to the 534 + registers for applications that require it. 529 535 530 536 config HANGCHECK_TIMER 531 537 tristate "Hangcheck timer"
+24 -4
drivers/char/hpet.c
··· 367 367 return 0; 368 368 } 369 369 370 + #ifdef CONFIG_HPET_MMAP 371 + #ifdef CONFIG_HPET_MMAP_DEFAULT 372 + static int hpet_mmap_enabled = 1; 373 + #else 374 + static int hpet_mmap_enabled = 0; 375 + #endif 376 + 377 + static __init int hpet_mmap_enable(char *str) 378 + { 379 + get_option(&str, &hpet_mmap_enabled); 380 + pr_info("HPET mmap %s\n", hpet_mmap_enabled ? "enabled" : "disabled"); 381 + return 1; 382 + } 383 + __setup("hpet_mmap", hpet_mmap_enable); 384 + 370 385 static int hpet_mmap(struct file *file, struct vm_area_struct *vma) 371 386 { 372 - #ifdef CONFIG_HPET_MMAP 373 387 struct hpet_dev *devp; 374 388 unsigned long addr; 389 + 390 + if (!hpet_mmap_enabled) 391 + return -EACCES; 375 392 376 393 devp = file->private_data; 377 394 addr = devp->hd_hpets->hp_hpet_phys; ··· 398 381 399 382 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 400 383 return vm_iomap_memory(vma, addr, PAGE_SIZE); 401 - #else 402 - return -ENOSYS; 403 - #endif 404 384 } 385 + #else 386 + static int hpet_mmap(struct file *file, struct vm_area_struct *vma) 387 + { 388 + return -ENOSYS; 389 + } 390 + #endif 405 391 406 392 static int hpet_fasync(int fd, struct file *file, int on) 407 393 {