[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <85ca9ae1-d319-ee77-4a71-bc9c7874f2cb@yandex.ru>
Date: Sat, 10 Dec 2022 14:08:21 +0500
From: stsp <stsp2@...dex.ru>
To: linux-kernel@...r.kernel.org
Cc: linux-x86_64@...r.kernel.org, luto@...nel.org
Subject: strange behavior with sigreturn() to 32bit
Hi.
I am playing with 32bit compatibility segments,
and I am observing something very strange.
To demonstrate the problem, I did the change
to the kernel sigreturn test-case, and it is attached.
The change just moves the magic value to EAX
and calls an interrupt that produces a SIGSEGV.
The SIGSEGV handler prints the needed regs.
This patch intentionally adds 0x100000000 to
the RIP register, because AFAIK the high part
or 64bit regs are irrelevant in compatibility mode.
Now with high part of RIP non-zero, we see this:
$ ./sigreturn_64
err=0 trapno=d ax=0 ip=100000003
OK, obviously our asm code didn't execute -
why is so? How does the high part of RIP
affect compatibility mode?
Then lets start the same example under gdb:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000403008 in int31 ()
(gdb)
Continuing.
err=18a trapno=d ax=a5f3 ip=403008
Wow! Much better now: error code is correct,
ax is correct, but ip is invalid.
Now lets remove that high-part trashing from
source and recompile, then run again:
$ ./sigreturn_64
err=0 trapno=d ax=a5f3 ip=6
This time error code is incorrect! All other
values are good.
Lets see under gdb:
err=18a trapno=d ax=a5f3 ip=403008
Cool, under gdb the err code fixed itself but
IP is wrong...
Can anyone make any sense out of this? :)
To me it seems completely chaotic and I
suspect both sigreturn() and ptrace() are
somehow "broken" here.
View attachment "a.diff" of type "text/x-patch" (2463 bytes)
Powered by blists - more mailing lists