aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/ptrace.c34
-rw-r--r--arch/x86/kernel/signal_32.c11
-rw-r--r--arch/x86/kernel/signal_64.c49
3 files changed, 29 insertions, 65 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index e37dccce85db..19a7d2c40560 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/ptrace.h> 15#include <linux/ptrace.h>
16#include <linux/regset.h> 16#include <linux/regset.h>
17#include <linux/tracehook.h>
17#include <linux/user.h> 18#include <linux/user.h>
18#include <linux/elf.h> 19#include <linux/elf.h>
19#include <linux/security.h> 20#include <linux/security.h>
@@ -1375,30 +1376,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
1375 force_sig_info(SIGTRAP, &info, tsk); 1376 force_sig_info(SIGTRAP, &info, tsk);
1376} 1377}
1377 1378
1378static void syscall_trace(struct pt_regs *regs)
1379{
1380 if (!(current->ptrace & PT_PTRACED))
1381 return;
1382
1383#if 0
1384 printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
1385 current->comm,
1386 regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
1387 current_thread_info()->flags, current->ptrace);
1388#endif
1389
1390 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
1391 ? 0x80 : 0));
1392 /*
1393 * this isn't the same as continuing with a signal, but it will do
1394 * for normal use. strace only continues with a signal if the
1395 * stopping signal is not SIGTRAP. -brl
1396 */
1397 if (current->exit_code) {
1398 send_sig(current->exit_code, current, 1);
1399 current->exit_code = 0;
1400 }
1401}
1402 1379
1403#ifdef CONFIG_X86_32 1380#ifdef CONFIG_X86_32
1404# define IS_IA32 1 1381# define IS_IA32 1
@@ -1432,8 +1409,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
1432 if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) 1409 if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
1433 ret = -1L; 1410 ret = -1L;
1434 1411
1435 if (ret || test_thread_flag(TIF_SYSCALL_TRACE)) 1412 if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
1436 syscall_trace(regs); 1413 tracehook_report_syscall_entry(regs))
1414 ret = -1L;
1437 1415
1438 if (unlikely(current->audit_context)) { 1416 if (unlikely(current->audit_context)) {
1439 if (IS_IA32) 1417 if (IS_IA32)
@@ -1459,7 +1437,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1459 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); 1437 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
1460 1438
1461 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1439 if (test_thread_flag(TIF_SYSCALL_TRACE))
1462 syscall_trace(regs); 1440 tracehook_report_syscall_exit(regs, 0);
1463 1441
1464 /* 1442 /*
1465 * If TIF_SYSCALL_EMU is set, we only get here because of 1443 * If TIF_SYSCALL_EMU is set, we only get here because of
@@ -1475,6 +1453,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1475 * system call instruction. 1453 * system call instruction.
1476 */ 1454 */
1477 if (test_thread_flag(TIF_SINGLESTEP) && 1455 if (test_thread_flag(TIF_SINGLESTEP) &&
1478 (current->ptrace & PT_PTRACED)) 1456 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
1479 send_sigtrap(current, regs, 0); 1457 send_sigtrap(current, regs, 0);
1480} 1458}
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 6fb5bcdd8933..4445d26efd47 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/wait.h> 19#include <linux/wait.h>
20#include <linux/tracehook.h>
20#include <linux/elf.h> 21#include <linux/elf.h>
21#include <linux/smp.h> 22#include <linux/smp.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
@@ -558,8 +559,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
558 * handler too. 559 * handler too.
559 */ 560 */
560 regs->flags &= ~X86_EFLAGS_TF; 561 regs->flags &= ~X86_EFLAGS_TF;
561 if (test_thread_flag(TIF_SINGLESTEP))
562 ptrace_notify(SIGTRAP);
563 562
564 spin_lock_irq(&current->sighand->siglock); 563 spin_lock_irq(&current->sighand->siglock);
565 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 564 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -568,6 +567,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
568 recalc_sigpending(); 567 recalc_sigpending();
569 spin_unlock_irq(&current->sighand->siglock); 568 spin_unlock_irq(&current->sighand->siglock);
570 569
570 tracehook_signal_handler(sig, info, ka, regs,
571 test_thread_flag(TIF_SINGLESTEP));
572
571 return 0; 573 return 0;
572} 574}
573 575
@@ -661,5 +663,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
661 if (thread_info_flags & _TIF_SIGPENDING) 663 if (thread_info_flags & _TIF_SIGPENDING)
662 do_signal(regs); 664 do_signal(regs);
663 665
666 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
667 clear_thread_flag(TIF_NOTIFY_RESUME);
668 tracehook_notify_resume(regs);
669 }
670
664 clear_thread_flag(TIF_IRET); 671 clear_thread_flag(TIF_IRET);
665} 672}
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index b45ef8ddd651..d01e3f6ef26d 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -15,6 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/wait.h> 16#include <linux/wait.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/tracehook.h>
18#include <linux/unistd.h> 19#include <linux/unistd.h>
19#include <linux/stddef.h> 20#include <linux/stddef.h>
20#include <linux/personality.h> 21#include <linux/personality.h>
@@ -26,6 +27,7 @@
26#include <asm/proto.h> 27#include <asm/proto.h>
27#include <asm/ia32_unistd.h> 28#include <asm/ia32_unistd.h>
28#include <asm/mce.h> 29#include <asm/mce.h>
30#include <asm/syscall.h>
29#include "sigframe.h" 31#include "sigframe.h"
30 32
31#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -346,35 +348,6 @@ give_sigsegv:
346} 348}
347 349
348/* 350/*
349 * Return -1L or the syscall number that @regs is executing.
350 */
351static long current_syscall(struct pt_regs *regs)
352{
353 /*
354 * We always sign-extend a -1 value being set here,
355 * so this is always either -1L or a syscall number.
356 */
357 return regs->orig_ax;
358}
359
360/*
361 * Return a value that is -EFOO if the system call in @regs->orig_ax
362 * returned an error. This only works for @regs from @current.
363 */
364static long current_syscall_ret(struct pt_regs *regs)
365{
366#ifdef CONFIG_IA32_EMULATION
367 if (test_thread_flag(TIF_IA32))
368 /*
369 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
370 * and will match correctly in comparisons.
371 */
372 return (int) regs->ax;
373#endif
374 return regs->ax;
375}
376
377/*
378 * OK, we're invoking a handler 351 * OK, we're invoking a handler
379 */ 352 */
380 353
@@ -385,9 +358,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
385 int ret; 358 int ret;
386 359
387 /* Are we from a system call? */ 360 /* Are we from a system call? */
388 if (current_syscall(regs) >= 0) { 361 if (syscall_get_nr(current, regs) >= 0) {
389 /* If so, check system call restarting.. */ 362 /* If so, check system call restarting.. */
390 switch (current_syscall_ret(regs)) { 363 switch (syscall_get_error(current, regs)) {
391 case -ERESTART_RESTARTBLOCK: 364 case -ERESTART_RESTARTBLOCK:
392 case -ERESTARTNOHAND: 365 case -ERESTARTNOHAND:
393 regs->ax = -EINTR; 366 regs->ax = -EINTR;
@@ -444,8 +417,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
444 * handler too. 417 * handler too.
445 */ 418 */
446 regs->flags &= ~X86_EFLAGS_TF; 419 regs->flags &= ~X86_EFLAGS_TF;
447 if (test_thread_flag(TIF_SINGLESTEP))
448 ptrace_notify(SIGTRAP);
449 420
450 spin_lock_irq(&current->sighand->siglock); 421 spin_lock_irq(&current->sighand->siglock);
451 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 422 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -453,6 +424,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
453 sigaddset(&current->blocked,sig); 424 sigaddset(&current->blocked,sig);
454 recalc_sigpending(); 425 recalc_sigpending();
455 spin_unlock_irq(&current->sighand->siglock); 426 spin_unlock_irq(&current->sighand->siglock);
427
428 tracehook_signal_handler(sig, info, ka, regs,
429 test_thread_flag(TIF_SINGLESTEP));
456 } 430 }
457 431
458 return ret; 432 return ret;
@@ -509,9 +483,9 @@ static void do_signal(struct pt_regs *regs)
509 } 483 }
510 484
511 /* Did we come from a system call? */ 485 /* Did we come from a system call? */
512 if (current_syscall(regs) >= 0) { 486 if (syscall_get_nr(current, regs) >= 0) {
513 /* Restart the system call - no handlers present */ 487 /* Restart the system call - no handlers present */
514 switch (current_syscall_ret(regs)) { 488 switch (syscall_get_error(current, regs)) {
515 case -ERESTARTNOHAND: 489 case -ERESTARTNOHAND:
516 case -ERESTARTSYS: 490 case -ERESTARTSYS:
517 case -ERESTARTNOINTR: 491 case -ERESTARTNOINTR:
@@ -549,6 +523,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
549 /* deal with pending signal delivery */ 523 /* deal with pending signal delivery */
550 if (thread_info_flags & _TIF_SIGPENDING) 524 if (thread_info_flags & _TIF_SIGPENDING)
551 do_signal(regs); 525 do_signal(regs);
526
527 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
528 clear_thread_flag(TIF_NOTIFY_RESUME);
529 tracehook_notify_resume(regs);
530 }
552} 531}
553 532
554void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 533void signal_fault(struct pt_regs *regs, void __user *frame, char *where)