diff options
author | Oleg Nesterov <oleg@redhat.com> | 2013-07-08 19:00:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 13:33:25 -0400 |
commit | 02be46fba4b154b4a201a729b2d2b4ff6affd031 (patch) | |
tree | ab4e9dd91918dda1e6474855065018a5c331fcaa /arch/x86 | |
parent | 6e5b93ee55d401f1619092fb675b57c28c9ed7ec (diff) |
ptrace/x86: revert "hw_breakpoints: Fix racy access to ptrace breakpoints"
This reverts commit 87dc669ba257 ("hw_breakpoints: Fix racy access to
ptrace breakpoints").
The patch was fine but we can no longer race with SIGKILL after commit
9899d11f6544 ("ptrace: ensure arch_ptrace/ptrace_request can never race
with SIGKILL"), the __TASK_TRACED tracee can't be woken up and
->ptrace_bps[] can't go away.
The patch only removes ptrace_get_breakpoints/ptrace_put_breakpoints and
does a couple of "while at it" cleanups, it doesn't remove other changes
from the reverted commit.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Michael Neuling <mikey@neuling.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Prasad <prasad@linux.vnet.ibm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/ptrace.c | 28 |
1 files changed, 5 insertions, 23 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 29a8120e6fe8..7a98b21945aa 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -641,9 +641,6 @@ static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data) | |||
641 | unsigned len, type; | 641 | unsigned len, type; |
642 | struct perf_event *bp; | 642 | struct perf_event *bp; |
643 | 643 | ||
644 | if (ptrace_get_breakpoints(tsk) < 0) | ||
645 | return -ESRCH; | ||
646 | |||
647 | data &= ~DR_CONTROL_RESERVED; | 644 | data &= ~DR_CONTROL_RESERVED; |
648 | old_dr7 = ptrace_get_dr7(thread->ptrace_bps); | 645 | old_dr7 = ptrace_get_dr7(thread->ptrace_bps); |
649 | restore: | 646 | restore: |
@@ -692,9 +689,7 @@ restore: | |||
692 | goto restore; | 689 | goto restore; |
693 | } | 690 | } |
694 | 691 | ||
695 | ptrace_put_breakpoints(tsk); | 692 | return orig_ret < 0 ? orig_ret : rc; |
696 | |||
697 | return ((orig_ret < 0) ? orig_ret : rc); | ||
698 | } | 693 | } |
699 | 694 | ||
700 | /* | 695 | /* |
@@ -706,18 +701,10 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) | |||
706 | unsigned long val = 0; | 701 | unsigned long val = 0; |
707 | 702 | ||
708 | if (n < HBP_NUM) { | 703 | if (n < HBP_NUM) { |
709 | struct perf_event *bp; | 704 | struct perf_event *bp = thread->ptrace_bps[n]; |
710 | 705 | ||
711 | if (ptrace_get_breakpoints(tsk) < 0) | 706 | if (bp) |
712 | return -ESRCH; | ||
713 | |||
714 | bp = thread->ptrace_bps[n]; | ||
715 | if (!bp) | ||
716 | val = 0; | ||
717 | else | ||
718 | val = bp->hw.info.address; | 707 | val = bp->hw.info.address; |
719 | |||
720 | ptrace_put_breakpoints(tsk); | ||
721 | } else if (n == 6) { | 708 | } else if (n == 6) { |
722 | val = thread->debugreg6; | 709 | val = thread->debugreg6; |
723 | } else if (n == 7) { | 710 | } else if (n == 7) { |
@@ -734,9 +721,6 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
734 | struct perf_event_attr attr; | 721 | struct perf_event_attr attr; |
735 | int err = 0; | 722 | int err = 0; |
736 | 723 | ||
737 | if (ptrace_get_breakpoints(tsk) < 0) | ||
738 | return -ESRCH; | ||
739 | |||
740 | if (!t->ptrace_bps[nr]) { | 724 | if (!t->ptrace_bps[nr]) { |
741 | ptrace_breakpoint_init(&attr); | 725 | ptrace_breakpoint_init(&attr); |
742 | /* | 726 | /* |
@@ -762,7 +746,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
762 | */ | 746 | */ |
763 | if (IS_ERR(bp)) { | 747 | if (IS_ERR(bp)) { |
764 | err = PTR_ERR(bp); | 748 | err = PTR_ERR(bp); |
765 | goto put; | 749 | goto out; |
766 | } | 750 | } |
767 | 751 | ||
768 | t->ptrace_bps[nr] = bp; | 752 | t->ptrace_bps[nr] = bp; |
@@ -773,9 +757,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
773 | attr.bp_addr = addr; | 757 | attr.bp_addr = addr; |
774 | err = modify_user_hw_breakpoint(bp, &attr); | 758 | err = modify_user_hw_breakpoint(bp, &attr); |
775 | } | 759 | } |
776 | 760 | out: | |
777 | put: | ||
778 | ptrace_put_breakpoints(tsk); | ||
779 | return err; | 761 | return err; |
780 | } | 762 | } |
781 | 763 | ||