ptrace.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /* ptrace.c: Sparc process tracing support.
  2. *
  3. * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
  4. * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5. *
  6. * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
  7. * and David Mosberger.
  8. *
  9. * Added Linux support -miguel (weird, eh?, the original code was meant
  10. * to emulate SunOS).
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/mm.h>
  15. #include <linux/errno.h>
  16. #include <linux/ptrace.h>
  17. #include <linux/user.h>
  18. #include <linux/smp.h>
  19. #include <linux/smp_lock.h>
  20. #include <linux/security.h>
  21. #include <linux/seccomp.h>
  22. #include <linux/audit.h>
  23. #include <linux/signal.h>
  24. #include <asm/asi.h>
  25. #include <asm/pgtable.h>
  26. #include <asm/system.h>
  27. #include <asm/uaccess.h>
  28. #include <asm/psrcompat.h>
  29. #include <asm/visasm.h>
  30. #include <asm/spitfire.h>
  31. /* Returning from ptrace is a bit tricky because the syscall return
  32. * low level code assumes any value returned which is negative and
  33. * is a valid errno will mean setting the condition codes to indicate
  34. * an error return. This doesn't work, so we have this hook.
  35. */
  36. static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
  37. {
  38. regs->u_regs[UREG_I0] = error;
  39. regs->tstate |= (TSTATE_ICARRY | TSTATE_XCARRY);
  40. regs->tpc = regs->tnpc;
  41. regs->tnpc += 4;
  42. }
  43. static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
  44. {
  45. regs->u_regs[UREG_I0] = value;
  46. regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
  47. regs->tpc = regs->tnpc;
  48. regs->tnpc += 4;
  49. }
  50. static inline void
  51. pt_succ_return_linux(struct pt_regs *regs, unsigned long value, void __user *addr)
  52. {
  53. if (test_thread_flag(TIF_32BIT)) {
  54. if (put_user(value, (unsigned int __user *) addr)) {
  55. pt_error_return(regs, EFAULT);
  56. return;
  57. }
  58. } else {
  59. if (put_user(value, (long __user *) addr)) {
  60. pt_error_return(regs, EFAULT);
  61. return;
  62. }
  63. }
  64. regs->u_regs[UREG_I0] = 0;
  65. regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
  66. regs->tpc = regs->tnpc;
  67. regs->tnpc += 4;
  68. }
  69. static void
  70. pt_os_succ_return (struct pt_regs *regs, unsigned long val, void __user *addr)
  71. {
  72. if (current->personality == PER_SUNOS)
  73. pt_succ_return (regs, val);
  74. else
  75. pt_succ_return_linux (regs, val, addr);
  76. }
  77. /* #define ALLOW_INIT_TRACING */
  78. /* #define DEBUG_PTRACE */
  79. #ifdef DEBUG_PTRACE
  80. char *pt_rq [] = {
  81. /* 0 */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
  82. /* 4 */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
  83. /* 8 */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
  84. /* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
  85. /* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
  86. /* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
  87. /* 24 */ "SYSCALL", ""
  88. };
  89. #endif
  90. /*
  91. * Called by kernel/ptrace.c when detaching..
  92. *
  93. * Make sure single step bits etc are not set.
  94. */
  95. void ptrace_disable(struct task_struct *child)
  96. {
  97. /* nothing to do */
  98. }
  99. /* To get the necessary page struct, access_process_vm() first calls
  100. * get_user_pages(). This has done a flush_dcache_page() on the
  101. * accessed page. Then our caller (copy_{to,from}_user_page()) did
  102. * to memcpy to read/write the data from that page.
  103. *
  104. * Now, the only thing we have to do is:
  105. * 1) flush the D-cache if it's possible than an illegal alias
  106. * has been created
  107. * 2) flush the I-cache if this is pre-cheetah and we did a write
  108. */
  109. void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
  110. unsigned long uaddr, void *kaddr,
  111. unsigned long len, int write)
  112. {
  113. BUG_ON(len > PAGE_SIZE);
  114. #ifdef DCACHE_ALIASING_POSSIBLE
  115. /* If bit 13 of the kernel address we used to access the
  116. * user page is the same as the virtual address that page
  117. * is mapped to in the user's address space, we can skip the
  118. * D-cache flush.
  119. */
  120. if ((uaddr ^ kaddr) & (1UL << 13)) {
  121. unsigned long start = __pa(kaddr);
  122. unsigned long end = start + len;
  123. if (tlb_type == spitfire) {
  124. for (; start < end; start += 32)
  125. spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
  126. } else {
  127. for (; start < end; start += 32)
  128. __asm__ __volatile__(
  129. "stxa %%g0, [%0] %1\n\t"
  130. "membar #Sync"
  131. : /* no outputs */
  132. : "r" (va),
  133. "i" (ASI_DCACHE_INVALIDATE));
  134. }
  135. }
  136. #endif
  137. if (write && tlb_type == spitfire) {
  138. unsigned long start = (unsigned long) kaddr;
  139. unsigned long end = start + len;
  140. for (; start < end; start += 32)
  141. flushi(start);
  142. }
  143. }
  144. asmlinkage void do_ptrace(struct pt_regs *regs)
  145. {
  146. int request = regs->u_regs[UREG_I0];
  147. pid_t pid = regs->u_regs[UREG_I1];
  148. unsigned long addr = regs->u_regs[UREG_I2];
  149. unsigned long data = regs->u_regs[UREG_I3];
  150. unsigned long addr2 = regs->u_regs[UREG_I4];
  151. struct task_struct *child;
  152. int ret;
  153. if (test_thread_flag(TIF_32BIT)) {
  154. addr &= 0xffffffffUL;
  155. data &= 0xffffffffUL;
  156. addr2 &= 0xffffffffUL;
  157. }
  158. lock_kernel();
  159. #ifdef DEBUG_PTRACE
  160. {
  161. char *s;
  162. if ((request >= 0) && (request <= 24))
  163. s = pt_rq [request];
  164. else
  165. s = "unknown";
  166. if (request == PTRACE_POKEDATA && data == 0x91d02001){
  167. printk ("do_ptrace: breakpoint pid=%d, addr=%016lx addr2=%016lx\n",
  168. pid, addr, addr2);
  169. } else
  170. printk("do_ptrace: rq=%s(%d) pid=%d addr=%016lx data=%016lx addr2=%016lx\n",
  171. s, request, pid, addr, data, addr2);
  172. }
  173. #endif
  174. if (request == PTRACE_TRACEME) {
  175. int ret;
  176. /* are we already being traced? */
  177. if (current->ptrace & PT_PTRACED) {
  178. pt_error_return(regs, EPERM);
  179. goto out;
  180. }
  181. ret = security_ptrace(current->parent, current);
  182. if (ret) {
  183. pt_error_return(regs, -ret);
  184. goto out;
  185. }
  186. /* set the ptrace bit in the process flags. */
  187. current->ptrace |= PT_PTRACED;
  188. pt_succ_return(regs, 0);
  189. goto out;
  190. }
  191. #ifndef ALLOW_INIT_TRACING
  192. if (pid == 1) {
  193. /* Can't dork with init. */
  194. pt_error_return(regs, EPERM);
  195. goto out;
  196. }
  197. #endif
  198. read_lock(&tasklist_lock);
  199. child = find_task_by_pid(pid);
  200. if (child)
  201. get_task_struct(child);
  202. read_unlock(&tasklist_lock);
  203. if (!child) {
  204. pt_error_return(regs, ESRCH);
  205. goto out;
  206. }
  207. if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
  208. || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
  209. if (ptrace_attach(child)) {
  210. pt_error_return(regs, EPERM);
  211. goto out_tsk;
  212. }
  213. pt_succ_return(regs, 0);
  214. goto out_tsk;
  215. }
  216. ret = ptrace_check_attach(child, request == PTRACE_KILL);
  217. if (ret < 0) {
  218. pt_error_return(regs, -ret);
  219. goto out_tsk;
  220. }
  221. if (!(test_thread_flag(TIF_32BIT)) &&
  222. ((request == PTRACE_READDATA64) ||
  223. (request == PTRACE_WRITEDATA64) ||
  224. (request == PTRACE_READTEXT64) ||
  225. (request == PTRACE_WRITETEXT64) ||
  226. (request == PTRACE_PEEKTEXT64) ||
  227. (request == PTRACE_POKETEXT64) ||
  228. (request == PTRACE_PEEKDATA64) ||
  229. (request == PTRACE_POKEDATA64))) {
  230. addr = regs->u_regs[UREG_G2];
  231. addr2 = regs->u_regs[UREG_G3];
  232. request -= 30; /* wheee... */
  233. }
  234. switch(request) {
  235. case PTRACE_PEEKTEXT: /* read word at location addr. */
  236. case PTRACE_PEEKDATA: {
  237. unsigned long tmp64;
  238. unsigned int tmp32;
  239. int res, copied;
  240. res = -EIO;
  241. if (test_thread_flag(TIF_32BIT)) {
  242. copied = access_process_vm(child, addr,
  243. &tmp32, sizeof(tmp32), 0);
  244. tmp64 = (unsigned long) tmp32;
  245. if (copied == sizeof(tmp32))
  246. res = 0;
  247. } else {
  248. copied = access_process_vm(child, addr,
  249. &tmp64, sizeof(tmp64), 0);
  250. if (copied == sizeof(tmp64))
  251. res = 0;
  252. }
  253. if (res < 0)
  254. pt_error_return(regs, -res);
  255. else
  256. pt_os_succ_return(regs, tmp64, (void __user *) data);
  257. goto out_tsk;
  258. }
  259. case PTRACE_POKETEXT: /* write the word at location addr. */
  260. case PTRACE_POKEDATA: {
  261. unsigned long tmp64;
  262. unsigned int tmp32;
  263. int copied, res = -EIO;
  264. if (test_thread_flag(TIF_32BIT)) {
  265. tmp32 = data;
  266. copied = access_process_vm(child, addr,
  267. &tmp32, sizeof(tmp32), 1);
  268. if (copied == sizeof(tmp32))
  269. res = 0;
  270. } else {
  271. tmp64 = data;
  272. copied = access_process_vm(child, addr,
  273. &tmp64, sizeof(tmp64), 1);
  274. if (copied == sizeof(tmp64))
  275. res = 0;
  276. }
  277. if (res < 0)
  278. pt_error_return(regs, -res);
  279. else
  280. pt_succ_return(regs, res);
  281. goto out_tsk;
  282. }
  283. case PTRACE_GETREGS: {
  284. struct pt_regs32 __user *pregs =
  285. (struct pt_regs32 __user *) addr;
  286. struct pt_regs *cregs = child->thread_info->kregs;
  287. int rval;
  288. if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
  289. __put_user(cregs->tpc, (&pregs->pc)) ||
  290. __put_user(cregs->tnpc, (&pregs->npc)) ||
  291. __put_user(cregs->y, (&pregs->y))) {
  292. pt_error_return(regs, EFAULT);
  293. goto out_tsk;
  294. }
  295. for (rval = 1; rval < 16; rval++)
  296. if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
  297. pt_error_return(regs, EFAULT);
  298. goto out_tsk;
  299. }
  300. pt_succ_return(regs, 0);
  301. #ifdef DEBUG_PTRACE
  302. printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
  303. #endif
  304. goto out_tsk;
  305. }
  306. case PTRACE_GETREGS64: {
  307. struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
  308. struct pt_regs *cregs = child->thread_info->kregs;
  309. unsigned long tpc = cregs->tpc;
  310. int rval;
  311. if ((child->thread_info->flags & _TIF_32BIT) != 0)
  312. tpc &= 0xffffffff;
  313. if (__put_user(cregs->tstate, (&pregs->tstate)) ||
  314. __put_user(tpc, (&pregs->tpc)) ||
  315. __put_user(cregs->tnpc, (&pregs->tnpc)) ||
  316. __put_user(cregs->y, (&pregs->y))) {
  317. pt_error_return(regs, EFAULT);
  318. goto out_tsk;
  319. }
  320. for (rval = 1; rval < 16; rval++)
  321. if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
  322. pt_error_return(regs, EFAULT);
  323. goto out_tsk;
  324. }
  325. pt_succ_return(regs, 0);
  326. #ifdef DEBUG_PTRACE
  327. printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
  328. #endif
  329. goto out_tsk;
  330. }
  331. case PTRACE_SETREGS: {
  332. struct pt_regs32 __user *pregs =
  333. (struct pt_regs32 __user *) addr;
  334. struct pt_regs *cregs = child->thread_info->kregs;
  335. unsigned int psr, pc, npc, y;
  336. int i;
  337. /* Must be careful, tracing process can only set certain
  338. * bits in the psr.
  339. */
  340. if (__get_user(psr, (&pregs->psr)) ||
  341. __get_user(pc, (&pregs->pc)) ||
  342. __get_user(npc, (&pregs->npc)) ||
  343. __get_user(y, (&pregs->y))) {
  344. pt_error_return(regs, EFAULT);
  345. goto out_tsk;
  346. }
  347. cregs->tstate &= ~(TSTATE_ICC);
  348. cregs->tstate |= psr_to_tstate_icc(psr);
  349. if (!((pc | npc) & 3)) {
  350. cregs->tpc = pc;
  351. cregs->tnpc = npc;
  352. }
  353. cregs->y = y;
  354. for (i = 1; i < 16; i++) {
  355. if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
  356. pt_error_return(regs, EFAULT);
  357. goto out_tsk;
  358. }
  359. }
  360. pt_succ_return(regs, 0);
  361. goto out_tsk;
  362. }
  363. case PTRACE_SETREGS64: {
  364. struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
  365. struct pt_regs *cregs = child->thread_info->kregs;
  366. unsigned long tstate, tpc, tnpc, y;
  367. int i;
  368. /* Must be careful, tracing process can only set certain
  369. * bits in the psr.
  370. */
  371. if (__get_user(tstate, (&pregs->tstate)) ||
  372. __get_user(tpc, (&pregs->tpc)) ||
  373. __get_user(tnpc, (&pregs->tnpc)) ||
  374. __get_user(y, (&pregs->y))) {
  375. pt_error_return(regs, EFAULT);
  376. goto out_tsk;
  377. }
  378. if ((child->thread_info->flags & _TIF_32BIT) != 0) {
  379. tpc &= 0xffffffff;
  380. tnpc &= 0xffffffff;
  381. }
  382. tstate &= (TSTATE_ICC | TSTATE_XCC);
  383. cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
  384. cregs->tstate |= tstate;
  385. if (!((tpc | tnpc) & 3)) {
  386. cregs->tpc = tpc;
  387. cregs->tnpc = tnpc;
  388. }
  389. cregs->y = y;
  390. for (i = 1; i < 16; i++) {
  391. if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
  392. pt_error_return(regs, EFAULT);
  393. goto out_tsk;
  394. }
  395. }
  396. pt_succ_return(regs, 0);
  397. goto out_tsk;
  398. }
  399. case PTRACE_GETFPREGS: {
  400. struct fps {
  401. unsigned int regs[32];
  402. unsigned int fsr;
  403. unsigned int flags;
  404. unsigned int extra;
  405. unsigned int fpqd;
  406. struct fq {
  407. unsigned int insnaddr;
  408. unsigned int insn;
  409. } fpq[16];
  410. };
  411. struct fps __user *fps = (struct fps __user *) addr;
  412. unsigned long *fpregs = child->thread_info->fpregs;
  413. if (copy_to_user(&fps->regs[0], fpregs,
  414. (32 * sizeof(unsigned int))) ||
  415. __put_user(child->thread_info->xfsr[0], (&fps->fsr)) ||
  416. __put_user(0, (&fps->fpqd)) ||
  417. __put_user(0, (&fps->flags)) ||
  418. __put_user(0, (&fps->extra)) ||
  419. clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
  420. pt_error_return(regs, EFAULT);
  421. goto out_tsk;
  422. }
  423. pt_succ_return(regs, 0);
  424. goto out_tsk;
  425. }
  426. case PTRACE_GETFPREGS64: {
  427. struct fps {
  428. unsigned int regs[64];
  429. unsigned long fsr;
  430. };
  431. struct fps __user *fps = (struct fps __user *) addr;
  432. unsigned long *fpregs = child->thread_info->fpregs;
  433. if (copy_to_user(&fps->regs[0], fpregs,
  434. (64 * sizeof(unsigned int))) ||
  435. __put_user(child->thread_info->xfsr[0], (&fps->fsr))) {
  436. pt_error_return(regs, EFAULT);
  437. goto out_tsk;
  438. }
  439. pt_succ_return(regs, 0);
  440. goto out_tsk;
  441. }
  442. case PTRACE_SETFPREGS: {
  443. struct fps {
  444. unsigned int regs[32];
  445. unsigned int fsr;
  446. unsigned int flags;
  447. unsigned int extra;
  448. unsigned int fpqd;
  449. struct fq {
  450. unsigned int insnaddr;
  451. unsigned int insn;
  452. } fpq[16];
  453. };
  454. struct fps __user *fps = (struct fps __user *) addr;
  455. unsigned long *fpregs = child->thread_info->fpregs;
  456. unsigned fsr;
  457. if (copy_from_user(fpregs, &fps->regs[0],
  458. (32 * sizeof(unsigned int))) ||
  459. __get_user(fsr, (&fps->fsr))) {
  460. pt_error_return(regs, EFAULT);
  461. goto out_tsk;
  462. }
  463. child->thread_info->xfsr[0] &= 0xffffffff00000000UL;
  464. child->thread_info->xfsr[0] |= fsr;
  465. if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
  466. child->thread_info->gsr[0] = 0;
  467. child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
  468. pt_succ_return(regs, 0);
  469. goto out_tsk;
  470. }
  471. case PTRACE_SETFPREGS64: {
  472. struct fps {
  473. unsigned int regs[64];
  474. unsigned long fsr;
  475. };
  476. struct fps __user *fps = (struct fps __user *) addr;
  477. unsigned long *fpregs = child->thread_info->fpregs;
  478. if (copy_from_user(fpregs, &fps->regs[0],
  479. (64 * sizeof(unsigned int))) ||
  480. __get_user(child->thread_info->xfsr[0], (&fps->fsr))) {
  481. pt_error_return(regs, EFAULT);
  482. goto out_tsk;
  483. }
  484. if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
  485. child->thread_info->gsr[0] = 0;
  486. child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
  487. pt_succ_return(regs, 0);
  488. goto out_tsk;
  489. }
  490. case PTRACE_READTEXT:
  491. case PTRACE_READDATA: {
  492. int res = ptrace_readdata(child, addr,
  493. (char __user *)addr2, data);
  494. if (res == data) {
  495. pt_succ_return(regs, 0);
  496. goto out_tsk;
  497. }
  498. if (res >= 0)
  499. res = -EIO;
  500. pt_error_return(regs, -res);
  501. goto out_tsk;
  502. }
  503. case PTRACE_WRITETEXT:
  504. case PTRACE_WRITEDATA: {
  505. int res = ptrace_writedata(child, (char __user *) addr2,
  506. addr, data);
  507. if (res == data) {
  508. pt_succ_return(regs, 0);
  509. goto out_tsk;
  510. }
  511. if (res >= 0)
  512. res = -EIO;
  513. pt_error_return(regs, -res);
  514. goto out_tsk;
  515. }
  516. case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
  517. addr = 1;
  518. case PTRACE_CONT: { /* restart after signal. */
  519. if (!valid_signal(data)) {
  520. pt_error_return(regs, EIO);
  521. goto out_tsk;
  522. }
  523. if (request == PTRACE_SYSCALL) {
  524. set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
  525. } else {
  526. clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
  527. }
  528. child->exit_code = data;
  529. #ifdef DEBUG_PTRACE
  530. printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
  531. child->pid, child->exit_code,
  532. child->thread_info->kregs->tpc,
  533. child->thread_info->kregs->tnpc);
  534. #endif
  535. wake_up_process(child);
  536. pt_succ_return(regs, 0);
  537. goto out_tsk;
  538. }
  539. /*
  540. * make the child exit. Best I can do is send it a sigkill.
  541. * perhaps it should be put in the status that it wants to
  542. * exit.
  543. */
  544. case PTRACE_KILL: {
  545. if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
  546. pt_succ_return(regs, 0);
  547. goto out_tsk;
  548. }
  549. child->exit_code = SIGKILL;
  550. wake_up_process(child);
  551. pt_succ_return(regs, 0);
  552. goto out_tsk;
  553. }
  554. case PTRACE_SUNDETACH: { /* detach a process that was attached. */
  555. int error = ptrace_detach(child, data);
  556. if (error) {
  557. pt_error_return(regs, EIO);
  558. goto out_tsk;
  559. }
  560. pt_succ_return(regs, 0);
  561. goto out_tsk;
  562. }
  563. /* PTRACE_DUMPCORE unsupported... */
  564. default: {
  565. int err = ptrace_request(child, request, addr, data);
  566. if (err)
  567. pt_error_return(regs, -err);
  568. else
  569. pt_succ_return(regs, 0);
  570. goto out_tsk;
  571. }
  572. }
  573. out_tsk:
  574. if (child)
  575. put_task_struct(child);
  576. out:
  577. unlock_kernel();
  578. }
  579. asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
  580. {
  581. /* do the secure computing check first */
  582. secure_computing(regs->u_regs[UREG_G1]);
  583. if (unlikely(current->audit_context) && syscall_exit_p) {
  584. unsigned long tstate = regs->tstate;
  585. int result = AUDITSC_SUCCESS;
  586. if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
  587. result = AUDITSC_FAILURE;
  588. audit_syscall_exit(current, result, regs->u_regs[UREG_I0]);
  589. }
  590. if (!(current->ptrace & PT_PTRACED))
  591. goto out;
  592. if (!test_thread_flag(TIF_SYSCALL_TRACE))
  593. goto out;
  594. ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
  595. ? 0x80 : 0));
  596. /*
  597. * this isn't the same as continuing with a signal, but it will do
  598. * for normal use. strace only continues with a signal if the
  599. * stopping signal is not SIGTRAP. -brl
  600. */
  601. if (current->exit_code) {
  602. send_sig(current->exit_code, current, 1);
  603. current->exit_code = 0;
  604. }
  605. out:
  606. if (unlikely(current->audit_context) && !syscall_exit_p)
  607. audit_syscall_entry(current,
  608. (test_thread_flag(TIF_32BIT) ?
  609. AUDIT_ARCH_SPARC :
  610. AUDIT_ARCH_SPARC64),
  611. regs->u_regs[UREG_G1],
  612. regs->u_regs[UREG_I0],
  613. regs->u_regs[UREG_I1],
  614. regs->u_regs[UREG_I2],
  615. regs->u_regs[UREG_I3]);
  616. }