diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index c2964d890c9a..ca651ac00660 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -832,6 +832,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, | |||
832 | unsigned long addr = *ppos; | 832 | unsigned long addr = *ppos; |
833 | ssize_t copied; | 833 | ssize_t copied; |
834 | char *page; | 834 | char *page; |
835 | unsigned int flags; | ||
835 | 836 | ||
836 | if (!mm) | 837 | if (!mm) |
837 | return 0; | 838 | return 0; |
@@ -844,6 +845,11 @@ static ssize_t mem_rw(struct file *file, char __user *buf, | |||
844 | if (!atomic_inc_not_zero(&mm->mm_users)) | 845 | if (!atomic_inc_not_zero(&mm->mm_users)) |
845 | goto free; | 846 | goto free; |
846 | 847 | ||
848 | /* Maybe we should limit FOLL_FORCE to actual ptrace users? */ | ||
849 | flags = FOLL_FORCE; | ||
850 | if (write) | ||
851 | flags |= FOLL_WRITE; | ||
852 | |||
847 | while (count > 0) { | 853 | while (count > 0) { |
848 | int this_len = min_t(int, count, PAGE_SIZE); | 854 | int this_len = min_t(int, count, PAGE_SIZE); |
849 | 855 | ||
@@ -852,7 +858,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, | |||
852 | break; | 858 | break; |
853 | } | 859 | } |
854 | 860 | ||
855 | this_len = access_remote_vm(mm, addr, page, this_len, write); | 861 | this_len = access_remote_vm(mm, addr, page, this_len, flags); |
856 | if (!this_len) { | 862 | if (!this_len) { |
857 | if (!copied) | 863 | if (!copied) |
858 | copied = -EIO; | 864 | copied = -EIO; |
@@ -964,8 +970,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, | |||
964 | max_len = min_t(size_t, PAGE_SIZE, count); | 970 | max_len = min_t(size_t, PAGE_SIZE, count); |
965 | this_len = min(max_len, this_len); | 971 | this_len = min(max_len, this_len); |
966 | 972 | ||
967 | retval = access_remote_vm(mm, (env_start + src), | 973 | retval = access_remote_vm(mm, (env_start + src), page, this_len, 0); |
968 | page, this_len, 0); | ||
969 | 974 | ||
970 | if (retval <= 0) { | 975 | if (retval <= 0) { |
971 | ret = retval; | 976 | ret = retval; |
@@ -1007,6 +1012,9 @@ static ssize_t auxv_read(struct file *file, char __user *buf, | |||
1007 | { | 1012 | { |
1008 | struct mm_struct *mm = file->private_data; | 1013 | struct mm_struct *mm = file->private_data; |
1009 | unsigned int nwords = 0; | 1014 | unsigned int nwords = 0; |
1015 | |||
1016 | if (!mm) | ||
1017 | return 0; | ||
1010 | do { | 1018 | do { |
1011 | nwords += 2; | 1019 | nwords += 2; |
1012 | } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ | 1020 | } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |