qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: qemu-ppc64-linux-user: signal handler endianness in elfv2


From: Vincent Fazio
Subject: Re: qemu-ppc64-linux-user: signal handler endianness in elfv2
Date: Wed, 19 Feb 2020 07:56:58 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1

David,

On 2/18/20 9:14 PM, David Gibson wrote:
On Sat, Feb 08, 2020 at 12:57:40PM -0600, Vincent Fazio wrote:
I ran into a crash scenario in ppc64-linux-user when trying to run openssl
compiled with gcc & musl which emits an ELFv2 binary. The target CPU was a
big endian model (e6500)

Example:


vfazio@vfazio1 ~/development/buildroot/output/target :( $ gdb
~/development/qemu/ppc64-linux-user/qemu-ppc64
(gdb) run -d guest_errors -cpu e6500 -E 
LD_LIBRARY_PATH="/home/vfazio/development/buildroot/output/target/lib/:/home/vfazio/development/buildroot/output/target/usr/lib/"
lib/libc.so bin/bash
Starting program: /home/vfazio/development/qemu/ppc64-linux-user/qemu-ppc64
-d guest_errors -cpu e6500 -E 
LD_LIBRARY_PATH="/home/vfazio/development/buildroot/output/target/lib/:/home/vfazio/development/buildroot/output/target/usr/lib/"
lib/libc.so bin/bash
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7ff9700 (LWP 27186)]
invalid/unsupported opcode: 1f - 0c - 1a - 00 (7c005698) 0000000010028e58 0

Thread 1 "qemu-ppc64" received signal SIGSEGV, Segmentation fault.
0x00000000600a9257 in ldl_he_p (ptr=0x4c2c061000000000) at
/home/vfazio/development/qemu/include/qemu/bswap.h:351
351        __builtin_memcpy(&r, ptr, sizeof(r));

(gdb) !readelf -h bin/bash | grep abi
   Flags:                             0x2, abiv2
(gdb) !readelf -h lib/libc.so | grep abi
   Flags:                             0x2, abiv2
<<<<<

openssl does "probing" for PPC features (Altivec, Crypto, etc) by trying to
execute possibly illegal instructions and handling them... hence that
SIGILL. The problem is when it comes to jumping to the signal handler


#0  0x00000000600a9257 in ldl_he_p (ptr=0x4c2c061000000000) at
/home/vfazio/development/qemu/include/qemu/bswap.h:351
#1  0x00000000600a92fe in ldl_be_p (ptr=0x4c2c061000000000) at
/home/vfazio/development/qemu/include/qemu/bswap.h:449
#2  0x00000000600c0790 in translator_ldl_swap (env=0x62923150,
pc=5488768711647035392, do_swap=false) at
/home/vfazio/development/qemu/include/exec/translator.h:201
#3  0x000000006011c1ab in ppc_tr_translate_insn (dcbase=0x7fffffffd250,
cs=0x6291ae80) at /home/vfazio/development/qemu/target/ppc/translate.c:7856
#4  0x000000006005ae70 in translator_loop (ops=0x60805fc0 <ppc_tr_ops>,
db=0x7fffffffd250, cpu=0x6291ae80, tb=0x60a5f900
<static_code_gen_buffer+1681600>, max_insns=512)
     at /home/vfazio/development/qemu/accel/tcg/translator.c:102
<<<<<

The handler has what looks like an LE address but then swaps it since the
host is LE and the target is BE

setup_rt_frame (sig=4, ka=0x628c5f80 <sigact_table+96>, info=0x62931658,
set=0x7fffffffd2f8, env=0x62923150) at
/home/vfazio/development/qemu/linux-user/ppc/signal.c:575
575            qemu_log_mask(LOG_GUEST_ERROR, "sa_handler NIP to "
TARGET_FMT_lx "\n", ka->_sa_handler);
(gdb) p/x ka->_sa_handler
$11 = 0x10062c4c
579            env->nip = tswapl((target_ulong) ka->_sa_handler);
(gdb) p/x env->nip
$12 = 0x4c2c061000000000
<<<<<

the memcpy later faults because that's obviously not a valid address from
which to grab the PPC instructions that need to be translated.

I'm not familiar with the ELFv2 ABI or PPC assembly in general, so I'm not
sure what to expect here. Typically ELFv2 was reserved for ppc64le, but musl
uses ELFv2 for all ppc64 targets. This likely wouldn't be an issue in
ppc64LE since x86_64 is LE as well and no swap would take place.

Is the signal handler address tied to the endianess of the host? I noticed
there was no swapping in elfload.c so wasn't sure...removing the swap gets
me a little further in program execution but i do eventually crash (but that
may not be related to this specific issue).
I've had a look at this code, and as far as I can reason the tswap
here is correct.  I think the error must be somewhere else.

AFAICT, the ka structure is a verbatim copy of the sigaction structure
that the target supplied earlier with sigaction().  So, it should be
in target endianness.  env->nip needs to be in host endianness, so a
tswap() looks right.

I think we need to look earlier to see how an apparently LE value is
getting into the sigaction structure with a BE binary.

I've been a bit tied up with some other stuff so haven't been able to look at this like i wanted but please let me know if there's something i can do to help in the short term. Should i disassemble the binary and pastebin it somewhere?

Otherwise i can post a buildroot config for the toolchain and binaries to look at the compile process.

I can maybe get some time today to run this again and step through the signal setup and see if i can identify the LE signal handler address location.


--
Vincent Fazio
Embedded Software Engineer - Linux
Extreme Engineering Solutions, Inc
http://www.xes-inc.com




reply via email to

[Prev in Thread] Current Thread [Next in Thread]