Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC]: Fix several regset and ptrace bugs.

+98 -52
+1 -1
arch/sparc/kernel/ptrace.c
··· 325 325 const struct user_regset_view *view; 326 326 int ret; 327 327 328 - view = task_user_regset_view(child); 328 + view = task_user_regset_view(current); 329 329 330 330 switch(request) { 331 331 case PTRACE_GETREGS: {
+97 -51
arch/sparc64/kernel/ptrace.c
··· 114 114 preempt_enable(); 115 115 } 116 116 117 + static int get_from_target(struct task_struct *target, unsigned long uaddr, 118 + void *kbuf, int len) 119 + { 120 + if (target == current) { 121 + if (copy_from_user(kbuf, (void __user *) uaddr, len)) 122 + return -EFAULT; 123 + } else { 124 + int len2 = access_process_vm(target, uaddr, kbuf, len, 0); 125 + if (len2 != len) 126 + return -EFAULT; 127 + } 128 + return 0; 129 + } 130 + 131 + static int set_to_target(struct task_struct *target, unsigned long uaddr, 132 + void *kbuf, int len) 133 + { 134 + if (target == current) { 135 + if (copy_to_user((void __user *) uaddr, kbuf, len)) 136 + return -EFAULT; 137 + } else { 138 + int len2 = access_process_vm(target, uaddr, kbuf, len, 1); 139 + if (len2 != len) 140 + return -EFAULT; 141 + } 142 + return 0; 143 + } 144 + 145 + static int regwindow64_get(struct task_struct *target, 146 + const struct pt_regs *regs, 147 + struct reg_window *wbuf) 148 + { 149 + unsigned long rw_addr = regs->u_regs[UREG_I6]; 150 + 151 + if (test_tsk_thread_flag(current, TIF_32BIT)) { 152 + struct reg_window32 win32; 153 + int i; 154 + 155 + if (get_from_target(target, rw_addr, &win32, sizeof(win32))) 156 + return -EFAULT; 157 + for (i = 0; i < 8; i++) 158 + wbuf->locals[i] = win32.locals[i]; 159 + for (i = 0; i < 8; i++) 160 + wbuf->ins[i] = win32.ins[i]; 161 + } else { 162 + rw_addr += STACK_BIAS; 163 + if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf))) 164 + return -EFAULT; 165 + } 166 + 167 + return 0; 168 + } 169 + 170 + static int regwindow64_set(struct task_struct *target, 171 + const struct pt_regs *regs, 172 + struct reg_window *wbuf) 173 + { 174 + unsigned long rw_addr = regs->u_regs[UREG_I6]; 175 + 176 + if (test_tsk_thread_flag(current, TIF_32BIT)) { 177 + struct reg_window32 win32; 178 + int i; 179 + 180 + for (i = 0; i < 8; i++) 181 + win32.locals[i] = wbuf->locals[i]; 182 + for (i = 0; i < 8; i++) 183 + win32.ins[i] = wbuf->ins[i]; 184 + 185 + if (set_to_target(target, rw_addr, &win32, sizeof(win32))) 186 + return -EFAULT; 187 + } else { 188 + rw_addr += STACK_BIAS; 189 + if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf))) 190 + return -EFAULT; 191 + } 192 + 193 + return 0; 194 + } 195 + 117 196 enum sparc_regset { 118 197 REGSET_GENERAL, 119 198 REGSET_FP, ··· 212 133 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 213 134 regs->u_regs, 214 135 0, 16 * sizeof(u64)); 215 - if (!ret) { 216 - unsigned long __user *reg_window = (unsigned long __user *) 217 - (regs->u_regs[UREG_I6] + STACK_BIAS); 218 - unsigned long window[16]; 136 + if (!ret && count && pos < (32 * sizeof(u64))) { 137 + struct reg_window window; 219 138 220 - if (target == current) { 221 - if (copy_from_user(window, reg_window, sizeof(window))) 222 - return -EFAULT; 223 - } else { 224 - if (access_process_vm(target, 225 - (unsigned long) reg_window, 226 - window, 227 - sizeof(window), 0) != 228 - sizeof(window)) 229 - return -EFAULT; 230 - } 231 - 139 + if (regwindow64_get(target, regs, &window)) 140 + return -EFAULT; 232 141 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, 233 - window, 142 + &window, 234 143 16 * sizeof(u64), 235 144 32 * sizeof(u64)); 236 145 } ··· 240 173 36 * sizeof(u64)); 241 174 } 242 175 243 - if (!ret) 176 + if (!ret) { 244 177 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 245 178 36 * sizeof(u64), -1); 246 179 180 + } 247 181 return ret; 248 182 } 249 183 ··· 262 194 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 263 195 regs->u_regs, 264 196 0, 16 * sizeof(u64)); 265 - if (!ret && count > 0) { 266 - unsigned long __user *reg_window = (unsigned long __user *) 267 - (regs->u_regs[UREG_I6] + STACK_BIAS); 268 - unsigned long window[16]; 197 + if (!ret && count && pos < (32 * sizeof(u64))) { 198 + struct reg_window window; 269 199 270 - if (target == current) { 271 - if (copy_from_user(window, reg_window, sizeof(window))) 272 - return -EFAULT; 273 - } else { 274 - if (access_process_vm(target, 275 - (unsigned long) reg_window, 276 - window, 277 - sizeof(window), 0) != 278 - sizeof(window)) 279 - return -EFAULT; 280 - } 200 + if (regwindow64_get(target, regs, &window)) 201 + return -EFAULT; 281 202 282 203 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, 283 - window, 204 + &window, 284 205 16 * sizeof(u64), 285 206 32 * sizeof(u64)); 286 - if (!ret) { 287 - if (target == current) { 288 - if (copy_to_user(reg_window, window, 289 - sizeof(window))) 290 - return -EFAULT; 291 - } else { 292 - if (access_process_vm(target, 293 - (unsigned long) 294 - reg_window, 295 - window, 296 - sizeof(window), 1) != 297 - sizeof(window)) 298 - return -EFAULT; 299 - } 300 - } 207 + 208 + if (!ret && 209 + regwindow64_set(target, regs, &window)) 210 + return -EFAULT; 301 211 } 302 212 303 213 if (!ret && count > 0) { ··· 851 805 long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 852 806 compat_ulong_t caddr, compat_ulong_t cdata) 853 807 { 854 - const struct user_regset_view *view = task_user_regset_view(child); 808 + const struct user_regset_view *view = task_user_regset_view(current); 855 809 compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4]; 856 810 struct pt_regs32 __user *pregs; 857 811 struct compat_fps __user *fps; ··· 959 913 960 914 long arch_ptrace(struct task_struct *child, long request, long addr, long data) 961 915 { 962 - const struct user_regset_view *view = task_user_regset_view(child); 916 + const struct user_regset_view *view = task_user_regset_view(current); 963 917 unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; 964 918 struct pt_regs __user *pregs; 965 919 struct fps __user *fps;