diff options
-rw-r--r-- | fs/proc/base.c | 13 | ||||
-rw-r--r-- | mm/util.c | 16 |
2 files changed, 22 insertions, 7 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index e665097c1da5..4f764c2ac1a5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -953,6 +953,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, | |||
953 | unsigned long src = *ppos; | 953 | unsigned long src = *ppos; |
954 | int ret = 0; | 954 | int ret = 0; |
955 | struct mm_struct *mm = file->private_data; | 955 | struct mm_struct *mm = file->private_data; |
956 | unsigned long env_start, env_end; | ||
956 | 957 | ||
957 | if (!mm) | 958 | if (!mm) |
958 | return 0; | 959 | return 0; |
@@ -964,19 +965,25 @@ static ssize_t environ_read(struct file *file, char __user *buf, | |||
964 | ret = 0; | 965 | ret = 0; |
965 | if (!atomic_inc_not_zero(&mm->mm_users)) | 966 | if (!atomic_inc_not_zero(&mm->mm_users)) |
966 | goto free; | 967 | goto free; |
968 | |||
969 | down_read(&mm->mmap_sem); | ||
970 | env_start = mm->env_start; | ||
971 | env_end = mm->env_end; | ||
972 | up_read(&mm->mmap_sem); | ||
973 | |||
967 | while (count > 0) { | 974 | while (count > 0) { |
968 | size_t this_len, max_len; | 975 | size_t this_len, max_len; |
969 | int retval; | 976 | int retval; |
970 | 977 | ||
971 | if (src >= (mm->env_end - mm->env_start)) | 978 | if (src >= (env_end - env_start)) |
972 | break; | 979 | break; |
973 | 980 | ||
974 | this_len = mm->env_end - (mm->env_start + src); | 981 | this_len = env_end - (env_start + src); |
975 | 982 | ||
976 | max_len = min_t(size_t, PAGE_SIZE, count); | 983 | max_len = min_t(size_t, PAGE_SIZE, count); |
977 | this_len = min(max_len, this_len); | 984 | this_len = min(max_len, this_len); |
978 | 985 | ||
979 | retval = access_remote_vm(mm, (mm->env_start + src), | 986 | retval = access_remote_vm(mm, (env_start + src), |
980 | page, this_len, 0); | 987 | page, this_len, 0); |
981 | 988 | ||
982 | if (retval <= 0) { | 989 | if (retval <= 0) { |
@@ -476,17 +476,25 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen) | |||
476 | int res = 0; | 476 | int res = 0; |
477 | unsigned int len; | 477 | unsigned int len; |
478 | struct mm_struct *mm = get_task_mm(task); | 478 | struct mm_struct *mm = get_task_mm(task); |
479 | unsigned long arg_start, arg_end, env_start, env_end; | ||
479 | if (!mm) | 480 | if (!mm) |
480 | goto out; | 481 | goto out; |
481 | if (!mm->arg_end) | 482 | if (!mm->arg_end) |
482 | goto out_mm; /* Shh! No looking before we're done */ | 483 | goto out_mm; /* Shh! No looking before we're done */ |
483 | 484 | ||
484 | len = mm->arg_end - mm->arg_start; | 485 | down_read(&mm->mmap_sem); |
486 | arg_start = mm->arg_start; | ||
487 | arg_end = mm->arg_end; | ||
488 | env_start = mm->env_start; | ||
489 | env_end = mm->env_end; | ||
490 | up_read(&mm->mmap_sem); | ||
491 | |||
492 | len = arg_end - arg_start; | ||
485 | 493 | ||
486 | if (len > buflen) | 494 | if (len > buflen) |
487 | len = buflen; | 495 | len = buflen; |
488 | 496 | ||
489 | res = access_process_vm(task, mm->arg_start, buffer, len, 0); | 497 | res = access_process_vm(task, arg_start, buffer, len, 0); |
490 | 498 | ||
491 | /* | 499 | /* |
492 | * If the nul at the end of args has been overwritten, then | 500 | * If the nul at the end of args has been overwritten, then |
@@ -497,10 +505,10 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen) | |||
497 | if (len < res) { | 505 | if (len < res) { |
498 | res = len; | 506 | res = len; |
499 | } else { | 507 | } else { |
500 | len = mm->env_end - mm->env_start; | 508 | len = env_end - env_start; |
501 | if (len > buflen - res) | 509 | if (len > buflen - res) |
502 | len = buflen - res; | 510 | len = buflen - res; |
503 | res += access_process_vm(task, mm->env_start, | 511 | res += access_process_vm(task, env_start, |
504 | buffer+res, len, 0); | 512 | buffer+res, len, 0); |
505 | res = strnlen(buffer, res); | 513 | res = strnlen(buffer, res); |
506 | } | 514 | } |