• Jason Wessel's avatar
    i386: fix infinite loop with singlestep int80 syscalls · bf35c377
    Jason Wessel authored
    The commit 635cf99a introduced a
    regression.  Executing a ptrace single step after certain int80
    accesses will infinitely loop and never advance the PC.
    
    The TIF_SINGLESTEP check should be done on the return from the syscall
    and not before it.
    
    The new test case is below:
    
    /* Test whether singlestep through an int80 syscall works.
     */
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ptrace.h>
    #include <sys/wait.h>
    #include <sys/mman.h>
    #include <asm/user.h>
    #include <string.h>
    
    static int child, status;
    static struct user_regs_struct regs;
    
    static void do_child()
    {
    	char str[80] = "child: int80 test\n";
    
    	ptrace(PTRACE_TRACEME, 0, 0, 0);
    	kill(getpid(), SIGUSR1);
    	write(fileno(stdout),str,strlen(str));
    	asm ("int $0x80" : : "a" (20)); /* getpid */
    }
        
    static void do_parent()
    {
    	unsigned long eip, expected = 0;
    again:
    	waitpid(child, &status, 0);
    	if (WIFEXITED(status) || WIFSIGNALED(status))
    		return;
        
    	if (WIFSTOPPED(status)) {
    		ptrace(PTRACE_GETREGS, child, 0, &regs);
    		eip = regs.eip;
    		if (expected)
    			fprintf(stderr, "child stop @ %08lx, expected %08lx %s\n",
    					eip, expected,
    					eip == expected ? "" : " <== ERROR");
        
    		if (*(unsigned short *)eip == 0x80cd) {
    			fprintf(stderr, "int 0x80 at %08x\n", (unsigned int)eip);
    			expected = eip + 2;
    		} else
    			expected = 0;
        
    		ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
    	}
    	goto again;
    }
        
    int main(int argc, char * const argv[])
    {
    	child = fork();
    	if (child)
    		do_parent();
    	else
    		do_child();
    	return 0;
    }
    Signed-off-by: default avatarJason Wessel <jason.wessel@windriver.com>
    Cc: Jeremy Fitzhardinge <jeremy@goop.org>
    Cc: Chuck Ebbert <cebbert@redhat.com>
    Signed-off-by: default avatarChris Wright <chrisw@sous-sol.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    bf35c377
entry.S 23.9 KB