diff options
| author | Jiri Olsa <jolsa@kernel.org> | 2016-09-08 03:57:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-20 16:32:49 -0400 |
| commit | f5beeb1851ea6f8cfcf2657f26cb24c0582b4945 (patch) | |
| tree | f619d5d6686ec8e43fe5f234c52f551f1febacad /fs/proc | |
| parent | d2ffb0103aaefa9b169da042cf39ce27bfb6cdbb (diff) | |
fs/proc/kcore.c: Make bounce buffer global for read
Next patch adds bounce buffer for ktext area, so it's
convenient to have single bounce buffer for both
vmalloc/module and ktext cases.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
| -rw-r--r-- | fs/proc/kcore.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index a939f5ed7f89..bd3ac9dca252 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
| @@ -430,6 +430,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
| 430 | static ssize_t | 430 | static ssize_t |
| 431 | read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) | 431 | read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) |
| 432 | { | 432 | { |
| 433 | char *buf = file->private_data; | ||
| 433 | ssize_t acc = 0; | 434 | ssize_t acc = 0; |
| 434 | size_t size, tsz; | 435 | size_t size, tsz; |
| 435 | size_t elf_buflen; | 436 | size_t elf_buflen; |
| @@ -500,18 +501,10 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) | |||
| 500 | if (clear_user(buffer, tsz)) | 501 | if (clear_user(buffer, tsz)) |
| 501 | return -EFAULT; | 502 | return -EFAULT; |
| 502 | } else if (is_vmalloc_or_module_addr((void *)start)) { | 503 | } else if (is_vmalloc_or_module_addr((void *)start)) { |
| 503 | char * elf_buf; | 504 | vread(buf, (char *)start, tsz); |
| 504 | |||
| 505 | elf_buf = kzalloc(tsz, GFP_KERNEL); | ||
| 506 | if (!elf_buf) | ||
| 507 | return -ENOMEM; | ||
| 508 | vread(elf_buf, (char *)start, tsz); | ||
| 509 | /* we have to zero-fill user buffer even if no read */ | 505 | /* we have to zero-fill user buffer even if no read */ |
| 510 | if (copy_to_user(buffer, elf_buf, tsz)) { | 506 | if (copy_to_user(buffer, buf, tsz)) |
| 511 | kfree(elf_buf); | ||
| 512 | return -EFAULT; | 507 | return -EFAULT; |
| 513 | } | ||
| 514 | kfree(elf_buf); | ||
| 515 | } else { | 508 | } else { |
| 516 | if (kern_addr_valid(start)) { | 509 | if (kern_addr_valid(start)) { |
| 517 | unsigned long n; | 510 | unsigned long n; |
| @@ -549,6 +542,11 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
| 549 | { | 542 | { |
| 550 | if (!capable(CAP_SYS_RAWIO)) | 543 | if (!capable(CAP_SYS_RAWIO)) |
| 551 | return -EPERM; | 544 | return -EPERM; |
| 545 | |||
| 546 | filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
| 547 | if (!filp->private_data) | ||
| 548 | return -ENOMEM; | ||
| 549 | |||
| 552 | if (kcore_need_update) | 550 | if (kcore_need_update) |
| 553 | kcore_update_ram(); | 551 | kcore_update_ram(); |
| 554 | if (i_size_read(inode) != proc_root_kcore->size) { | 552 | if (i_size_read(inode) != proc_root_kcore->size) { |
| @@ -559,10 +557,16 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
| 559 | return 0; | 557 | return 0; |
| 560 | } | 558 | } |
| 561 | 559 | ||
| 560 | static int release_kcore(struct inode *inode, struct file *file) | ||
| 561 | { | ||
| 562 | kfree(file->private_data); | ||
| 563 | return 0; | ||
| 564 | } | ||
| 562 | 565 | ||
| 563 | static const struct file_operations proc_kcore_operations = { | 566 | static const struct file_operations proc_kcore_operations = { |
| 564 | .read = read_kcore, | 567 | .read = read_kcore, |
| 565 | .open = open_kcore, | 568 | .open = open_kcore, |
| 569 | .release = release_kcore, | ||
| 566 | .llseek = default_llseek, | 570 | .llseek = default_llseek, |
| 567 | }; | 571 | }; |
| 568 | 572 | ||
