Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6961ed96 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

ptrace/powerpc: revert "hw_breakpoints: Fix racy access to ptrace breakpoints"



This reverts commit 07fa7a0a ("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
9899d11f ("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: default avatarOleg Nesterov <oleg@redhat.com>
Acked-by: default avatarMichael 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 02be46fb
Loading
Loading
Loading
Loading
+4 −26
Original line number Diff line number Diff line
@@ -975,16 +975,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
	hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
	hw_brk.len = 8;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	if (ptrace_get_breakpoints(task) < 0)
		return -ESRCH;

	bp = thread->ptrace_bps[0];
	if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) {
		if (bp) {
			unregister_hw_breakpoint(bp);
			thread->ptrace_bps[0] = NULL;
		}
		ptrace_put_breakpoints(task);
		return 0;
	}
	if (bp) {
@@ -997,11 +993,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,

		ret =  modify_user_hw_breakpoint(bp, &attr);
		if (ret) {
			ptrace_put_breakpoints(task);
			return ret;
		}
		thread->ptrace_bps[0] = bp;
		ptrace_put_breakpoints(task);
		thread->hw_brk = hw_brk;
		return 0;
	}
@@ -1016,12 +1010,9 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
					       ptrace_triggered, NULL, task);
	if (IS_ERR(bp)) {
		thread->ptrace_bps[0] = NULL;
		ptrace_put_breakpoints(task);
		return PTR_ERR(bp);
	}

	ptrace_put_breakpoints(task);

#endif /* CONFIG_HAVE_HW_BREAKPOINT */
	task->thread.hw_brk = hw_brk;
#else /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -1440,26 +1431,19 @@ static long ppc_set_hwdebug(struct task_struct *child,
	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
		brk.type |= HW_BRK_TYPE_WRITE;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	if (ptrace_get_breakpoints(child) < 0)
		return -ESRCH;

	/*
	 * Check if the request is for 'range' breakpoints. We can
	 * support it if range < 8 bytes.
	 */
	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
		len = bp_info->addr2 - bp_info->addr;
	} else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
	else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
		len = 1;
	else {
		ptrace_put_breakpoints(child);
	else
		return -EINVAL;
	}
	bp = thread->ptrace_bps[0];
	if (bp) {
		ptrace_put_breakpoints(child);
	if (bp)
		return -ENOSPC;
	}

	/* Create a new breakpoint request if one doesn't exist already */
	hw_breakpoint_init(&attr);
@@ -1471,11 +1455,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
					       ptrace_triggered, NULL, child);
	if (IS_ERR(bp)) {
		thread->ptrace_bps[0] = NULL;
		ptrace_put_breakpoints(child);
		return PTR_ERR(bp);
	}

	ptrace_put_breakpoints(child);
	return 1;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */

@@ -1519,16 +1501,12 @@ static long ppc_del_hwdebug(struct task_struct *child, long data)
		return -EINVAL;

#ifdef CONFIG_HAVE_HW_BREAKPOINT
	if (ptrace_get_breakpoints(child) < 0)
		return -ESRCH;

	bp = thread->ptrace_bps[0];
	if (bp) {
		unregister_hw_breakpoint(bp);
		thread->ptrace_bps[0] = NULL;
	} else
		ret = -ENOENT;
	ptrace_put_breakpoints(child);
	return ret;
#else /* CONFIG_HAVE_HW_BREAKPOINT */
	if (child->thread.hw_brk.address == 0)