aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/kcore.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-09-08 03:57:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-09-20 16:32:49 -0400
commitf5beeb1851ea6f8cfcf2657f26cb24c0582b4945 (patch)
treef619d5d6686ec8e43fe5f234c52f551f1febacad /fs/proc/kcore.c
parentd2ffb0103aaefa9b169da042cf39ce27bfb6cdbb (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/kcore.c')
-rw-r--r--fs/proc/kcore.c24
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)
430static ssize_t 430static ssize_t
431read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) 431read_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
560static int release_kcore(struct inode *inode, struct file *file)
561{
562 kfree(file->private_data);
563 return 0;
564}
562 565
563static const struct file_operations proc_kcore_operations = { 566static 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