From: Devin Hussey <husseydevin@gmail.com>
To: qemu-devel@nongnu.org
Subject: Issues with modifying pc in a sigaction handler
Date: Tue, 13 Apr 2021 18:03:52 -0400 [thread overview]
Message-ID: <CAEtFKsuPfRS1_exHPBNE-BLthbXoudUOcX6ND80FA=JqV8LrzA@mail.gmail.com> (raw)
In a toy project I was doing
(https://github.com/easyaspi314/ThumbGolf), I found that qemu will
incorrectly handle modifying pc in a handler.
Specifically, on platforms with instruction alignment requirements
(most notably ARM), if you set the pc to an odd address, QEMU will
start reading unaligned instructions.
Naturally, this is frustrating when dealing with ARM Thumb functions
which have the lowest bit set when referenced, as you must manually
clear the Thumb bit instead of it being implicit on hardware.
The following code exhibits this bug for ARM:
---
#include <signal.h>
#include <ucontext.h>
#include <stdio.h>
static void hello(void)
{
printf("Hello,");
}
static void handler(int signo, siginfo_t *si, void *data)
{
ucontext_t *uc = (ucontext_t *)data;
// Effectively bl hello although we assume thumb state
uc->uc_mcontext.arm_lr = uc->uc_mcontext.arm_pc + 2 | 1;
uc->uc_mcontext.arm_pc = (unsigned long)&hello;
}
int main(void)
{
// Set up the signal handler
struct sigaction sa, osa;
sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_NODEFER | SA_SIGINFO;
sa.sa_sigaction = handler;
sigaction(SIGILL, &sa, &osa);
sigaction(SIGTRAP, &sa, &osa);
// Throw a SIGILL, which we do a runtime patch to call hello().
// Make sure we mark the caller saved registers.
__asm__ ("udf #0" ::: "r0", "r1", "r2", "r3", "r12", "lr", "memory");
printf(" world!\n");
}
---
Compile with:
clang -O2 -march=armv7-a -mthumb file.c -static
(The same should happen with GCC).
On hardware (specifically, a Snapdragon 730g in Termux on Android 11),
the code prints "Hello, world!" and exits normally.
However, qemu-arm will get tripped up by the pc being odd, and execute this:
---
... snip
----------------
IN: main
0x00010288: 4c05 ldr r4, [pc, #0x14]
0x0001028a: de00 udf #0
----------------
IN: handler
0x000102a4: 4804 ldr r0, [pc, #0x10]
0x000102a6: 6dd1 ldr r1, [r2, #0x5c]
0x000102a8: 4478 add r0, pc
0x000102aa: 3102 adds r1, #2
0x000102ac: f041 0101 orr r1, r1, #1
0x000102b0: e9c2 1016 strd r1, r0, [r2, #0x58]
0x000102b4: 4770 bx lr
----------------
IN: __restore_rt
0x0004c36c: e3a070ad mov r7, #0xad
0x0004c370: ef000000 svc #0
----------------
IN: hello
0x000102bd: 7848 ldrb r0, [r1, #1]
0x000102bf: 0644 lsls r4, r0, #0x19
0x000102c1: 5cf0 ldrb r0, [r6, r3]
0x000102c3: 06bb lsls r3, r7, #0x1a
0x000102c5: 053e lsls r6, r7, #0x14
0x000102c7: f000 89b5 beq.w #0x90635
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
---
Note the odd addresses in hello().
It should be interpreted as so, which happens when you manually clear
the Thumb bit:
---
0x000102b8: 4801 ldr r0, [pc, #4]
0x000102ba: 4478 add r0, pc
0x000102bc: f006
bb5c b.w #0x16978 (printf)
---
next reply other threads:[~2021-04-13 22:44 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-13 22:03 Devin Hussey [this message]
2021-04-14 9:49 ` Issues with modifying pc in a sigaction handler Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAEtFKsuPfRS1_exHPBNE-BLthbXoudUOcX6ND80FA=JqV8LrzA@mail.gmail.com' \
--to=husseydevin@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).