diff options
author | Prarit Bhargava <prarit@redhat.com> | 2013-11-12 18:08:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 22:09:11 -0500 |
commit | 3d035f580699feba352f8703cced127fc203f0dd (patch) | |
tree | 9469709ea2eda88e66531edb865ab41757615a0d /drivers/char | |
parent | 72403b4a0fbdf433c1fe0127e49864658f6f6468 (diff) |
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Kconfig | 10 | ||||
-rw-r--r-- | drivers/char/hpet.c | 24 |
2 files changed, 30 insertions, 4 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 14219972c745..fa3243d71c76 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -522,10 +522,16 @@ config HPET_MMAP | |||
522 | If you say Y here, user applications will be able to mmap | 522 | If you say Y here, user applications will be able to mmap |
523 | the HPET registers. | 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 | In some hardware implementations, the page containing HPET | 530 | In some hardware implementations, the page containing HPET |
526 | registers may also contain other things that shouldn't be | 531 | registers may also contain other things that shouldn't be |
527 | exposed to the user. If this applies to your hardware, | 532 | exposed to the user. This option selects the default (if |
528 | say N here. | 533 | kernel parameter hpet_mmap is not set) user access to the |
534 | registers for applications that require it. | ||
529 | 535 | ||
530 | config HANGCHECK_TIMER | 536 | config HANGCHECK_TIMER |
531 | tristate "Hangcheck timer" | 537 | tristate "Hangcheck timer" |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index dca5834685cf..5d9c31dfc905 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -367,12 +367,29 @@ static unsigned int hpet_poll(struct file *file, poll_table * wait) | |||
367 | return 0; | 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 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | 385 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) |
371 | { | 386 | { |
372 | #ifdef CONFIG_HPET_MMAP | ||
373 | struct hpet_dev *devp; | 387 | struct hpet_dev *devp; |
374 | unsigned long addr; | 388 | unsigned long addr; |
375 | 389 | ||
390 | if (!hpet_mmap_enabled) | ||
391 | return -EACCES; | ||
392 | |||
376 | devp = file->private_data; | 393 | devp = file->private_data; |
377 | addr = devp->hd_hpets->hp_hpet_phys; | 394 | addr = devp->hd_hpets->hp_hpet_phys; |
378 | 395 | ||
@@ -381,10 +398,13 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
381 | 398 | ||
382 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 399 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
383 | return vm_iomap_memory(vma, addr, PAGE_SIZE); | 400 | return vm_iomap_memory(vma, addr, PAGE_SIZE); |
401 | } | ||
384 | #else | 402 | #else |
403 | static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | ||
404 | { | ||
385 | return -ENOSYS; | 405 | return -ENOSYS; |
386 | #endif | ||
387 | } | 406 | } |
407 | #endif | ||
388 | 408 | ||
389 | static int hpet_fasync(int fd, struct file *file, int on) | 409 | static int hpet_fasync(int fd, struct file *file, int on) |
390 | { | 410 | { |