• Oleg Nesterov's avatar
    uprobes/x86: Make arch_uretprobe_is_alive(RP_CHECK_CALL) more clever · db087ef6
    Oleg Nesterov authored
    The previous change documents that cleanup_return_instances()
    can't always detect the dead frames, the stack can grow. But
    there is one special case which imho worth fixing:
    arch_uretprobe_is_alive() can return true when the stack didn't
    actually grow, but the next "call" insn uses the already
    invalidated frame.
    
    Test-case:
    
    	#include <stdio.h>
    	#include <setjmp.h>
    
    	jmp_buf jmp;
    	int nr = 1024;
    
    	void func_2(void)
    	{
    		if (--nr == 0)
    			return;
    		longjmp(jmp, 1);
    	}
    
    	void func_1(void)
    	{
    		setjmp(jmp);
    		func_2();
    	}
    
    	int main(void)
    	{
    		func_1();
    		return 0;
    	}
    
    If you ret-probe func_1() and func_2() prepare_uretprobe() hits
    the MAX_URETPROBE_DEPTH limit and "return" from func_2() is not
    reported.
    
    When we know that the new call is not chained, we can do the
    more strict check. In this case "sp" points to the new ret-addr,
    so every frame which uses the same "sp" must be dead. The only
    complication is that arch_uretprobe_is_alive() needs to know was
    it chained or not, so we add the new RP_CHECK_CHAIN_CALL enum
    and change prepare_uretprobe() to pass RP_CHECK_CALL only if
    !chained.
    
    Note: arch_uretprobe_is_alive() could also re-read *sp and check
    if this word is still trampoline_vaddr. This could obviously
    improve the logic, but I would like to avoid another
    copy_from_user() especially in the case when we can't avoid the
    false "alive == T" positives.
    Tested-by: default avatarPratyush Anand <panand@redhat.com>
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    Acked-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
    Acked-by: default avatarAnton 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/20150721134028.GA4786@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    db087ef6
uprobes.c 32 KB