diff options
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r-- | arch/x86/kernel/ptrace.c | 95 |
1 files changed, 8 insertions, 87 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 559c1b027417..fb03ef380f0e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1207,97 +1207,16 @@ static int genregs32_set(struct task_struct *target, | |||
1207 | return ret; | 1207 | return ret; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data) | 1210 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
1211 | compat_ulong_t caddr, compat_ulong_t cdata) | ||
1211 | { | 1212 | { |
1212 | siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t)); | 1213 | unsigned long addr = caddr; |
1213 | compat_siginfo_t __user *si32 = compat_ptr(data); | 1214 | unsigned long data = cdata; |
1214 | siginfo_t ssi; | ||
1215 | int ret; | ||
1216 | |||
1217 | if (request == PTRACE_SETSIGINFO) { | ||
1218 | memset(&ssi, 0, sizeof(siginfo_t)); | ||
1219 | ret = copy_siginfo_from_user32(&ssi, si32); | ||
1220 | if (ret) | ||
1221 | return ret; | ||
1222 | if (copy_to_user(si, &ssi, sizeof(siginfo_t))) | ||
1223 | return -EFAULT; | ||
1224 | } | ||
1225 | ret = sys_ptrace(request, pid, addr, (unsigned long)si); | ||
1226 | if (ret) | ||
1227 | return ret; | ||
1228 | if (request == PTRACE_GETSIGINFO) { | ||
1229 | if (copy_from_user(&ssi, si, sizeof(siginfo_t))) | ||
1230 | return -EFAULT; | ||
1231 | ret = copy_siginfo_to_user32(si32, &ssi); | ||
1232 | } | ||
1233 | return ret; | ||
1234 | } | ||
1235 | |||
1236 | asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | ||
1237 | { | ||
1238 | struct task_struct *child; | ||
1239 | struct pt_regs *childregs; | ||
1240 | void __user *datap = compat_ptr(data); | 1215 | void __user *datap = compat_ptr(data); |
1241 | int ret; | 1216 | int ret; |
1242 | __u32 val; | 1217 | __u32 val; |
1243 | 1218 | ||
1244 | switch (request) { | 1219 | switch (request) { |
1245 | case PTRACE_TRACEME: | ||
1246 | case PTRACE_ATTACH: | ||
1247 | case PTRACE_KILL: | ||
1248 | case PTRACE_CONT: | ||
1249 | case PTRACE_SINGLESTEP: | ||
1250 | case PTRACE_SINGLEBLOCK: | ||
1251 | case PTRACE_DETACH: | ||
1252 | case PTRACE_SYSCALL: | ||
1253 | case PTRACE_OLDSETOPTIONS: | ||
1254 | case PTRACE_SETOPTIONS: | ||
1255 | case PTRACE_SET_THREAD_AREA: | ||
1256 | case PTRACE_GET_THREAD_AREA: | ||
1257 | #ifdef X86_BTS | ||
1258 | case PTRACE_BTS_CONFIG: | ||
1259 | case PTRACE_BTS_STATUS: | ||
1260 | case PTRACE_BTS_SIZE: | ||
1261 | case PTRACE_BTS_GET: | ||
1262 | case PTRACE_BTS_CLEAR: | ||
1263 | case PTRACE_BTS_DRAIN: | ||
1264 | #endif | ||
1265 | return sys_ptrace(request, pid, addr, data); | ||
1266 | |||
1267 | default: | ||
1268 | return -EINVAL; | ||
1269 | |||
1270 | case PTRACE_PEEKTEXT: | ||
1271 | case PTRACE_PEEKDATA: | ||
1272 | case PTRACE_POKEDATA: | ||
1273 | case PTRACE_POKETEXT: | ||
1274 | case PTRACE_POKEUSR: | ||
1275 | case PTRACE_PEEKUSR: | ||
1276 | case PTRACE_GETREGS: | ||
1277 | case PTRACE_SETREGS: | ||
1278 | case PTRACE_SETFPREGS: | ||
1279 | case PTRACE_GETFPREGS: | ||
1280 | case PTRACE_SETFPXREGS: | ||
1281 | case PTRACE_GETFPXREGS: | ||
1282 | case PTRACE_GETEVENTMSG: | ||
1283 | break; | ||
1284 | |||
1285 | case PTRACE_SETSIGINFO: | ||
1286 | case PTRACE_GETSIGINFO: | ||
1287 | return ptrace32_siginfo(request, pid, addr, data); | ||
1288 | } | ||
1289 | |||
1290 | child = ptrace_get_task_struct(pid); | ||
1291 | if (IS_ERR(child)) | ||
1292 | return PTR_ERR(child); | ||
1293 | |||
1294 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | ||
1295 | if (ret < 0) | ||
1296 | goto out; | ||
1297 | |||
1298 | childregs = task_pt_regs(child); | ||
1299 | |||
1300 | switch (request) { | ||
1301 | case PTRACE_PEEKUSR: | 1220 | case PTRACE_PEEKUSR: |
1302 | ret = getreg32(child, addr, &val); | 1221 | ret = getreg32(child, addr, &val); |
1303 | if (ret == 0) | 1222 | if (ret == 0) |
@@ -1343,12 +1262,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) | |||
1343 | sizeof(struct user32_fxsr_struct), | 1262 | sizeof(struct user32_fxsr_struct), |
1344 | datap); | 1263 | datap); |
1345 | 1264 | ||
1265 | case PTRACE_GET_THREAD_AREA: | ||
1266 | case PTRACE_SET_THREAD_AREA: | ||
1267 | return arch_ptrace(child, request, addr, data); | ||
1268 | |||
1346 | default: | 1269 | default: |
1347 | return compat_ptrace_request(child, request, addr, data); | 1270 | return compat_ptrace_request(child, request, addr, data); |
1348 | } | 1271 | } |
1349 | 1272 | ||
1350 | out: | ||
1351 | put_task_struct(child); | ||
1352 | return ret; | 1273 | return ret; |
1353 | } | 1274 | } |
1354 | 1275 | ||