[patch+7.5] Fix assertion fail on PaX gentoo (PR 14564)
Pedro Alves
palves@redhat.com
Mon Sep 10 13:59:00 GMT 2012
On 09/09/2012 03:22 PM, Jan Kratochvil wrote:
> static void
> linux_ptrace_test_ret_to_nx (void)
> {
> -#ifdef __i386__
> +#if defined __i386__ || defined __x86_64__
> pid_t child, got_pid;
> gdb_byte *return_address, *pc;
> long l;
> @@ -101,11 +103,21 @@ linux_ptrace_test_ret_to_nx (void)
> strerror (errno));
> else
> {
> +#if defined __i386__
> asm volatile ("pushl %0;"
> ".globl linux_ptrace_test_ret_to_nx_instr;"
> "linux_ptrace_test_ret_to_nx_instr:"
> "ret"
> : : "r" (return_address) : "%esp", "memory");
> +#elif defined __x86_64__
> + asm volatile ("pushq %0;"
> + ".globl linux_ptrace_test_ret_to_nx_instr;"
> + "linux_ptrace_test_ret_to_nx_instr:"
> + "ret"
> + : : "r" (return_address) : "%rsp", "memory");
> +#else
> +# error "!__i386__ && !__x86_64__"
> +#endif
> gdb_assert_not_reached ("asm block did not terminate");
> }
>
> @@ -114,13 +126,29 @@ linux_ptrace_test_ret_to_nx (void)
>
> got_pid = waitpid (child, &status, 0);
> gdb_assert (got_pid == child);
> +
> + if (WIFSIGNALED (status))
> + {
> + gdb_assert (WTERMSIG (status) == SIGKILL);
This, and the other assertions in the function make a little
nervous. It seems like one should be able to make them trigger
by sending a signal to gdb's process group, or "killall gdb" at
the wrong time? E.g., a SIGTERM, a SIGINT, or a SIGSTOP? The
linux_test_for_tracefork family of functions seems to warn
instead of asserting if something unexpected comes out of
ptrace/waitpid. Might be a good idea for this function too?
> +
> + warning (_("Cannot call inferior functions, Linux kernel PaX protection "
> + "forbids return to non-executable pages!"));
> + return;
> + }
> +
> gdb_assert (WIFSTOPPED (status));
>
> /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
> gdb_assert (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == SIGSEGV);
>
> errno = 0;
> +#if defined __i386__
> l = ptrace (PTRACE_PEEKUSER, child, (void *) (uintptr_t) (EIP * 4), NULL);
> +#elif defined __x86_64__
> + l = ptrace (PTRACE_PEEKUSER, child, (void *) (uintptr_t) (RIP * 8), NULL);
> +#else
> +# error "!__i386__ && !__x86_64__"
> +#endif
> gdb_assert (errno == 0);
> pc = (void *) (uintptr_t) l;
>
> @@ -154,7 +182,7 @@ linux_ptrace_test_ret_to_nx (void)
>
> warning (_("Cannot call inferior functions, you have broken "
> "Linux kernel i386 NX (non-executable pages) support!"));
> -#endif /* __i386__ */
> +#endif /* defined __i386__ || defined __x86_64__ */
> }
>
> /* Display possible problems on this system. Display them only once per GDB
>
--
Pedro Alves
More information about the Gdb-patches
mailing list