aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Pearson <james-p@moving-picture.com>2007-10-17 02:30:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:43:00 -0400
commit315e28c8d61560e90c7d9c7c56c1b661187ab307 (patch)
tree21edcc6d63a5cfb55cadfbfba9f205bb557d343c
parent3ad90ec0908e453ba89947fcf7b5f6821b6c1e0c (diff)
Don't truncate /proc/PID/environ at 4096 characters
/proc/PID/environ currently truncates at 4096 characters, patch based on the /proc/PID/mem code. Signed-off-by: James Pearson <james-p@moving-picture.com> Cc: Anton Arapov <aarapov@redhat.com> Cc: Jan Engelhardt <jengelh@computergmbh.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/proc/base.c95
1 files changed, 72 insertions, 23 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ea115d4c9f59..4fe74d156416 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -199,27 +199,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
199 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ 199 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
200 security_ptrace(current,task) == 0)) 200 security_ptrace(current,task) == 0))
201 201
202static int proc_pid_environ(struct task_struct *task, char * buffer)
203{
204 int res = 0;
205 struct mm_struct *mm = get_task_mm(task);
206 if (mm) {
207 unsigned int len;
208
209 res = -ESRCH;
210 if (!ptrace_may_attach(task))
211 goto out;
212
213 len = mm->env_end - mm->env_start;
214 if (len > PAGE_SIZE)
215 len = PAGE_SIZE;
216 res = access_process_vm(task, mm->env_start, buffer, len, 0);
217out:
218 mmput(mm);
219 }
220 return res;
221}
222
223static int proc_pid_cmdline(struct task_struct *task, char * buffer) 202static int proc_pid_cmdline(struct task_struct *task, char * buffer)
224{ 203{
225 int res = 0; 204 int res = 0;
@@ -658,6 +637,76 @@ static const struct file_operations proc_mem_operations = {
658 .open = mem_open, 637 .open = mem_open,
659}; 638};
660 639
640static ssize_t environ_read(struct file *file, char __user *buf,
641 size_t count, loff_t *ppos)
642{
643 struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
644 char *page;
645 unsigned long src = *ppos;
646 int ret = -ESRCH;
647 struct mm_struct *mm;
648
649 if (!task)
650 goto out_no_task;
651
652 if (!ptrace_may_attach(task))
653 goto out;
654
655 ret = -ENOMEM;
656 page = (char *)__get_free_page(GFP_TEMPORARY);
657 if (!page)
658 goto out;
659
660 ret = 0;
661
662 mm = get_task_mm(task);
663 if (!mm)
664 goto out_free;
665
666 while (count > 0) {
667 int this_len, retval, max_len;
668
669 this_len = mm->env_end - (mm->env_start + src);
670
671 if (this_len <= 0)
672 break;
673
674 max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
675 this_len = (this_len > max_len) ? max_len : this_len;
676
677 retval = access_process_vm(task, (mm->env_start + src),
678 page, this_len, 0);
679
680 if (retval <= 0) {
681 ret = retval;
682 break;
683 }
684
685 if (copy_to_user(buf, page, retval)) {
686 ret = -EFAULT;
687 break;
688 }
689
690 ret += retval;
691 src += retval;
692 buf += retval;
693 count -= retval;
694 }
695 *ppos = src;
696
697 mmput(mm);
698out_free:
699 free_page((unsigned long) page);
700out:
701 put_task_struct(task);
702out_no_task:
703 return ret;
704}
705
706static const struct file_operations proc_environ_operations = {
707 .read = environ_read,
708};
709
661static ssize_t oom_adjust_read(struct file *file, char __user *buf, 710static ssize_t oom_adjust_read(struct file *file, char __user *buf,
662 size_t count, loff_t *ppos) 711 size_t count, loff_t *ppos)
663{ 712{
@@ -2049,7 +2098,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2049 DIR("task", S_IRUGO|S_IXUGO, task), 2098 DIR("task", S_IRUGO|S_IXUGO, task),
2050 DIR("fd", S_IRUSR|S_IXUSR, fd), 2099 DIR("fd", S_IRUSR|S_IXUSR, fd),
2051 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2100 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
2052 INF("environ", S_IRUSR, pid_environ), 2101 REG("environ", S_IRUSR, environ),
2053 INF("auxv", S_IRUSR, pid_auxv), 2102 INF("auxv", S_IRUSR, pid_auxv),
2054 INF("status", S_IRUGO, pid_status), 2103 INF("status", S_IRUGO, pid_status),
2055#ifdef CONFIG_SCHED_DEBUG 2104#ifdef CONFIG_SCHED_DEBUG
@@ -2336,7 +2385,7 @@ out_no_task:
2336static const struct pid_entry tid_base_stuff[] = { 2385static const struct pid_entry tid_base_stuff[] = {
2337 DIR("fd", S_IRUSR|S_IXUSR, fd), 2386 DIR("fd", S_IRUSR|S_IXUSR, fd),
2338 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2387 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
2339 INF("environ", S_IRUSR, pid_environ), 2388 REG("environ", S_IRUSR, environ),
2340 INF("auxv", S_IRUSR, pid_auxv), 2389 INF("auxv", S_IRUSR, pid_auxv),
2341 INF("status", S_IRUGO, pid_status), 2390 INF("status", S_IRUGO, pid_status),
2342#ifdef CONFIG_SCHED_DEBUG 2391#ifdef CONFIG_SCHED_DEBUG