diff options
Diffstat (limited to 'kernel/ptrace.c')
| -rw-r--r-- | kernel/ptrace.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 2a99027312a6..e6474f7272ec 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -537,7 +537,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst | |||
| 537 | int this_len, retval; | 537 | int this_len, retval; |
| 538 | 538 | ||
| 539 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; | 539 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; |
| 540 | retval = access_process_vm(tsk, src, buf, this_len, 0); | 540 | retval = access_process_vm(tsk, src, buf, this_len, FOLL_FORCE); |
| 541 | if (!retval) { | 541 | if (!retval) { |
| 542 | if (copied) | 542 | if (copied) |
| 543 | break; | 543 | break; |
| @@ -564,7 +564,8 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds | |||
| 564 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; | 564 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; |
| 565 | if (copy_from_user(buf, src, this_len)) | 565 | if (copy_from_user(buf, src, this_len)) |
| 566 | return -EFAULT; | 566 | return -EFAULT; |
| 567 | retval = access_process_vm(tsk, dst, buf, this_len, 1); | 567 | retval = access_process_vm(tsk, dst, buf, this_len, |
| 568 | FOLL_FORCE | FOLL_WRITE); | ||
| 568 | if (!retval) { | 569 | if (!retval) { |
| 569 | if (copied) | 570 | if (copied) |
| 570 | break; | 571 | break; |
| @@ -1127,7 +1128,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, | |||
| 1127 | unsigned long tmp; | 1128 | unsigned long tmp; |
| 1128 | int copied; | 1129 | int copied; |
| 1129 | 1130 | ||
| 1130 | copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); | 1131 | copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), FOLL_FORCE); |
| 1131 | if (copied != sizeof(tmp)) | 1132 | if (copied != sizeof(tmp)) |
| 1132 | return -EIO; | 1133 | return -EIO; |
| 1133 | return put_user(tmp, (unsigned long __user *)data); | 1134 | return put_user(tmp, (unsigned long __user *)data); |
| @@ -1138,7 +1139,8 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, | |||
| 1138 | { | 1139 | { |
| 1139 | int copied; | 1140 | int copied; |
| 1140 | 1141 | ||
| 1141 | copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); | 1142 | copied = access_process_vm(tsk, addr, &data, sizeof(data), |
| 1143 | FOLL_FORCE | FOLL_WRITE); | ||
| 1142 | return (copied == sizeof(data)) ? 0 : -EIO; | 1144 | return (copied == sizeof(data)) ? 0 : -EIO; |
| 1143 | } | 1145 | } |
| 1144 | 1146 | ||
| @@ -1155,7 +1157,8 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, | |||
| 1155 | switch (request) { | 1157 | switch (request) { |
| 1156 | case PTRACE_PEEKTEXT: | 1158 | case PTRACE_PEEKTEXT: |
| 1157 | case PTRACE_PEEKDATA: | 1159 | case PTRACE_PEEKDATA: |
| 1158 | ret = access_process_vm(child, addr, &word, sizeof(word), 0); | 1160 | ret = access_process_vm(child, addr, &word, sizeof(word), |
| 1161 | FOLL_FORCE); | ||
| 1159 | if (ret != sizeof(word)) | 1162 | if (ret != sizeof(word)) |
| 1160 | ret = -EIO; | 1163 | ret = -EIO; |
| 1161 | else | 1164 | else |
| @@ -1164,7 +1167,8 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, | |||
| 1164 | 1167 | ||
| 1165 | case PTRACE_POKETEXT: | 1168 | case PTRACE_POKETEXT: |
| 1166 | case PTRACE_POKEDATA: | 1169 | case PTRACE_POKEDATA: |
| 1167 | ret = access_process_vm(child, addr, &data, sizeof(data), 1); | 1170 | ret = access_process_vm(child, addr, &data, sizeof(data), |
| 1171 | FOLL_FORCE | FOLL_WRITE); | ||
| 1168 | ret = (ret != sizeof(data) ? -EIO : 0); | 1172 | ret = (ret != sizeof(data) ? -EIO : 0); |
| 1169 | break; | 1173 | break; |
| 1170 | 1174 | ||
