[PATCH] display mask on enter to sigreturn, not exit

Denys Vlasenko dvlasenk at redhat.com
Wed Jan 18 10:09:58 UTC 2012


On 01/17/2012 10:46 PM, Dmitry V. Levin wrote:
> On Tue, Jan 17, 2012 at 08:59:46PM +0100, Denys Vlasenko wrote:
>> On 01/17/2012 08:43 PM, Dmitry V. Levin wrote:
>>> On Tue, Jan 17, 2012 at 08:01:00PM +0100, Denys Vlasenko wrote:
>>>> On 01/17/2012 07:53 PM, Dmitry V. Levin wrote:
>>> [...]
>>>>> [X86_64] (x86_64_regs): Remove.
>>>>> * syscall.c [X86_64] (x86_64_regs): Make static.
>>>>
>>>> I think we will eventually need register structs to be accessible
>>>> from all files. That's why I made x86_64_regs global too,
>>>> even though it does not have to be global (so far).
>>>>
>>>> I would like to ask for it to remain global.
>>>
>>> I'd probably agree, but the most astonishing thing is that global
>>> x86_64_regs doesn't work for me at all:
>>>
>>> $ ./strace /bin/true
>>> Segmentation fault
>>
>> Mysterious...
>
> There is no mystic, just a commonplace data corruption.
> On x86-64, sizeof(struct user_regs_struct) == 27 * sizeof(long),
> but sizeof(struct pt_regs) == 21 * sizeof(long).
>
> strace passes x86_64_regs of type "struct pt_regs" to PTRACE_GETREGS,
> which expects a pointer to "struct user_regs_struct", and happily
> overwrites 6 extra long words.  It could crash much earlier than now.
>
> We probably had to use user_regs_struct instead of pt_regs.

Looks that way - I checked glibc and kernel headers and.

I just committed the following change:

diff --git a/syscall.c b/syscall.c
index d356006..9c04cf9 100644
--- a/syscall.c
+++ b/syscall.c
@@ -737,7 +737,13 @@ struct tcb *tcp_last = NULL;
  # if defined(I386)
  struct pt_regs i386_regs;
  # elif defined(X86_64)
-static struct pt_regs x86_64_regs;
+/*
+ * On 32 bits, pt_regs and user_regs_struct are the same,
+ * but on 64 bits, user_regs_struct has six more fields:
+ * fs_base, gs_base, ds, es, fs, gs.
+ * PTRACE_GETREGS fills them too, so struct pt_regs would overflow.
+ */
+static struct user_regs_struct x86_64_regs;
  # elif defined (IA64)
  long r8, r10, psr; /* TODO: make static? */
  long ia32 = 0; /* not static */


-- 
vda




More information about the Strace-devel mailing list