mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	uprobes: Send SIGILL if handle_trampoline() fails
1. It doesn't make sense to continue if handle_trampoline() fails, change handle_swbp() to always return after this call. 2. Turn pr_warn() into uprobe_warn(), and change handle_trampoline() to send SIGILL on failure. It is pointless to return to user mode with the corrupted instruction_pointer() which we can't restore. Tested-by: Pratyush Anand <panand@redhat.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Acked-by: Anton Arapov <arapov@gmail.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20150721134008.GA4745@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									2bb5e840e8
								
							
						
					
					
						commit
						0b5256c7f1
					
				
					 1 changed files with 10 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -1770,7 +1770,7 @@ handle_uretprobe_chain(struct return_instance *ri, struct pt_regs *regs)
 | 
			
		|||
	up_read(&uprobe->register_rwsem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool handle_trampoline(struct pt_regs *regs)
 | 
			
		||||
static void handle_trampoline(struct pt_regs *regs)
 | 
			
		||||
{
 | 
			
		||||
	struct uprobe_task *utask;
 | 
			
		||||
	struct return_instance *ri;
 | 
			
		||||
| 
						 | 
				
			
			@ -1778,11 +1778,11 @@ static bool handle_trampoline(struct pt_regs *regs)
 | 
			
		|||
 | 
			
		||||
	utask = current->utask;
 | 
			
		||||
	if (!utask)
 | 
			
		||||
		return false;
 | 
			
		||||
		goto sigill;
 | 
			
		||||
 | 
			
		||||
	ri = utask->return_instances;
 | 
			
		||||
	if (!ri)
 | 
			
		||||
		return false;
 | 
			
		||||
		goto sigill;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * TODO: we should throw out return_instance's invalidated by
 | 
			
		||||
| 
						 | 
				
			
			@ -1804,8 +1804,12 @@ static bool handle_trampoline(struct pt_regs *regs)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	utask->return_instances = ri;
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
 sigill:
 | 
			
		||||
	uprobe_warn(current, "handle uretprobe, sending SIGILL.");
 | 
			
		||||
	force_sig_info(SIGILL, SEND_SIG_FORCED, current);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs)
 | 
			
		||||
| 
						 | 
				
			
			@ -1824,13 +1828,8 @@ static void handle_swbp(struct pt_regs *regs)
 | 
			
		|||
	int uninitialized_var(is_swbp);
 | 
			
		||||
 | 
			
		||||
	bp_vaddr = uprobe_get_swbp_addr(regs);
 | 
			
		||||
	if (bp_vaddr == get_trampoline_vaddr()) {
 | 
			
		||||
		if (handle_trampoline(regs))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		pr_warn("uprobe: unable to handle uretprobe pid/tgid=%d/%d\n",
 | 
			
		||||
						current->pid, current->tgid);
 | 
			
		||||
	}
 | 
			
		||||
	if (bp_vaddr == get_trampoline_vaddr())
 | 
			
		||||
		return handle_trampoline(regs);
 | 
			
		||||
 | 
			
		||||
	uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
 | 
			
		||||
	if (!uprobe) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue