aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-07-08 19:00:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 13:33:25 -0400
commit6961ed96f14463d7c6e38d8c2093f5d53bd70574 (patch)
tree210e317714fbee7abbe81f16f607693b00286364 /arch/powerpc
parent02be46fba4b154b4a201a729b2d2b4ff6affd031 (diff)
ptrace/powerpc: revert "hw_breakpoints: Fix racy access to ptrace breakpoints"
This reverts commit 07fa7a0a8a58 ("hw_breakpoints: Fix racy access to ptrace breakpoints") and removes ptrace_get/put_breakpoints() added by other commits. 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. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Michael Neuling <mikey@neuling.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jan Kratochvil <jan.kratochvil@redhat.com> 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/powerpc')
-rw-r--r--arch/powerpc/kernel/ptrace.c30
1 files changed, 4 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 64f7bd5b1b0f..9a0d24c390a3 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -975,16 +975,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
975 hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; 975 hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
976 hw_brk.len = 8; 976 hw_brk.len = 8;
977#ifdef CONFIG_HAVE_HW_BREAKPOINT 977#ifdef CONFIG_HAVE_HW_BREAKPOINT
978 if (ptrace_get_breakpoints(task) < 0)
979 return -ESRCH;
980
981 bp = thread->ptrace_bps[0]; 978 bp = thread->ptrace_bps[0];
982 if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) { 979 if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) {
983 if (bp) { 980 if (bp) {
984 unregister_hw_breakpoint(bp); 981 unregister_hw_breakpoint(bp);
985 thread->ptrace_bps[0] = NULL; 982 thread->ptrace_bps[0] = NULL;
986 } 983 }
987 ptrace_put_breakpoints(task);
988 return 0; 984 return 0;
989 } 985 }
990 if (bp) { 986 if (bp) {
@@ -997,11 +993,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
997 993
998 ret = modify_user_hw_breakpoint(bp, &attr); 994 ret = modify_user_hw_breakpoint(bp, &attr);
999 if (ret) { 995 if (ret) {
1000 ptrace_put_breakpoints(task);
1001 return ret; 996 return ret;
1002 } 997 }
1003 thread->ptrace_bps[0] = bp; 998 thread->ptrace_bps[0] = bp;
1004 ptrace_put_breakpoints(task);
1005 thread->hw_brk = hw_brk; 999 thread->hw_brk = hw_brk;
1006 return 0; 1000 return 0;
1007 } 1001 }
@@ -1016,12 +1010,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
1016 ptrace_triggered, NULL, task); 1010 ptrace_triggered, NULL, task);
1017 if (IS_ERR(bp)) { 1011 if (IS_ERR(bp)) {
1018 thread->ptrace_bps[0] = NULL; 1012 thread->ptrace_bps[0] = NULL;
1019 ptrace_put_breakpoints(task);
1020 return PTR_ERR(bp); 1013 return PTR_ERR(bp);
1021 } 1014 }
1022 1015
1023 ptrace_put_breakpoints(task);
1024
1025#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 1016#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1026 task->thread.hw_brk = hw_brk; 1017 task->thread.hw_brk = hw_brk;
1027#else /* CONFIG_PPC_ADV_DEBUG_REGS */ 1018#else /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -1440,26 +1431,19 @@ static long ppc_set_hwdebug(struct task_struct *child,
1440 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) 1431 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
1441 brk.type |= HW_BRK_TYPE_WRITE; 1432 brk.type |= HW_BRK_TYPE_WRITE;
1442#ifdef CONFIG_HAVE_HW_BREAKPOINT 1433#ifdef CONFIG_HAVE_HW_BREAKPOINT
1443 if (ptrace_get_breakpoints(child) < 0)
1444 return -ESRCH;
1445
1446 /* 1434 /*
1447 * Check if the request is for 'range' breakpoints. We can 1435 * Check if the request is for 'range' breakpoints. We can
1448 * support it if range < 8 bytes. 1436 * support it if range < 8 bytes.
1449 */ 1437 */
1450 if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) { 1438 if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
1451 len = bp_info->addr2 - bp_info->addr; 1439 len = bp_info->addr2 - bp_info->addr;
1452 } else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) 1440 else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
1453 len = 1; 1441 len = 1;
1454 else { 1442 else
1455 ptrace_put_breakpoints(child);
1456 return -EINVAL; 1443 return -EINVAL;
1457 }
1458 bp = thread->ptrace_bps[0]; 1444 bp = thread->ptrace_bps[0];
1459 if (bp) { 1445 if (bp)
1460 ptrace_put_breakpoints(child);
1461 return -ENOSPC; 1446 return -ENOSPC;
1462 }
1463 1447
1464 /* Create a new breakpoint request if one doesn't exist already */ 1448 /* Create a new breakpoint request if one doesn't exist already */
1465 hw_breakpoint_init(&attr); 1449 hw_breakpoint_init(&attr);
@@ -1471,11 +1455,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
1471 ptrace_triggered, NULL, child); 1455 ptrace_triggered, NULL, child);
1472 if (IS_ERR(bp)) { 1456 if (IS_ERR(bp)) {
1473 thread->ptrace_bps[0] = NULL; 1457 thread->ptrace_bps[0] = NULL;
1474 ptrace_put_breakpoints(child);
1475 return PTR_ERR(bp); 1458 return PTR_ERR(bp);
1476 } 1459 }
1477 1460
1478 ptrace_put_breakpoints(child);
1479 return 1; 1461 return 1;
1480#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 1462#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1481 1463
@@ -1519,16 +1501,12 @@ static long ppc_del_hwdebug(struct task_struct *child, long data)
1519 return -EINVAL; 1501 return -EINVAL;
1520 1502
1521#ifdef CONFIG_HAVE_HW_BREAKPOINT 1503#ifdef CONFIG_HAVE_HW_BREAKPOINT
1522 if (ptrace_get_breakpoints(child) < 0)
1523 return -ESRCH;
1524
1525 bp = thread->ptrace_bps[0]; 1504 bp = thread->ptrace_bps[0];
1526 if (bp) { 1505 if (bp) {
1527 unregister_hw_breakpoint(bp); 1506 unregister_hw_breakpoint(bp);
1528 thread->ptrace_bps[0] = NULL; 1507 thread->ptrace_bps[0] = NULL;
1529 } else 1508 } else
1530 ret = -ENOENT; 1509 ret = -ENOENT;
1531 ptrace_put_breakpoints(child);
1532 return ret; 1510 return ret;
1533#else /* CONFIG_HAVE_HW_BREAKPOINT */ 1511#else /* CONFIG_HAVE_HW_BREAKPOINT */
1534 if (child->thread.hw_brk.address == 0) 1512 if (child->thread.hw_brk.address == 0)