[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
qemu-user (arm64) fails (null ptr deref) under qemu-system-x86_64 w/o av
From: |
Michael Tokarev |
Subject: |
qemu-user (arm64) fails (null ptr deref) under qemu-system-x86_64 w/o avx? |
Date: |
Wed, 18 May 2022 12:13:38 +0300 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0 |
Hi!
Here's an interesting bug. Interesting because qemu-user does not run under
qemu-system.
Running 7.0.0 qemu-aarch64-static under 7.0.0 qemu-system-x86_64 -enable-kvm
with
default cpu type, getting:
Thread 1 "qemu-aarch64-static" received signal SIGSEGV, Segmentation fault.
0x00000000005d3db3 in fold_call (op=0xf2a4d8, ctx=0x7fffffffdf20)
at tcg/optimize.c:1215
bt:
#0 0x00000000005d3db3 in fold_call (op=0xf2a4d8, ctx=0x7fffffffdf20)
at tcg/optimize.c:1215
#1 tcg_optimize (s=s@entry=0xe3cf00 <tcg_init_ctx>)
at tcg/optimize.c:2049
#2 0x00000000005df5e1 in tcg_gen_code (s=0xe3cf00 <tcg_init_ctx>,
tb=tb@entry=0x7fffe8024580 <code_gen_buffer+148822>)
at tcg/tcg.c:4233
Code:
static bool fold_call(OptContext *ctx, TCGOp *op)
{
TCGContext *s = ctx->tcg;
int nb_oargs = TCGOP_CALLO(op);
int nb_iargs = TCGOP_CALLI(op);
int flags, i;
init_arguments(ctx, op, nb_oargs + nb_iargs);
copy_propagate(ctx, op, nb_oargs, nb_iargs);
/* If the function reads or writes globals, reset temp data. */
flags = tcg_call_flags(op); <==== here
if (!(flags & (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {
Disassembly:
0x5d3d93 <tcg_optimize+659> call 0x5d2da0 <copy_propagate>
0x5d3d98 <tcg_optimize+664> movzbl 0x1(%r15),%eax
0x5d3d9d <tcg_optimize+669> mov %eax,%edx
0x5d3d9f <tcg_optimize+671> and $0xf,%eax
0x5d3da2 <tcg_optimize+674> shr $0x4,%dl
0x5d3da5 <tcg_optimize+677> movzbl %dl,%edx
0x5d3da8 <tcg_optimize+680> lea 0x1(%rdx,%rax,1),%eax
0x5d3dac <tcg_optimize+684> cltq
0x5d3dae <tcg_optimize+686> mov 0x18(%r15,%rax,8),%rax
>0x5d3db3 <tcg_optimize+691> testb $0x3,0x10(%rax)
0x5d3db7 <tcg_optimize+695> jne 0x5d3e50 <tcg_optimize+848>
info registers:
rax 0x0 0
rbx 0xf2a558 15902040
rcx 0xe3e088 14934152
rdx 0x1 1
rsi 0x0 0
rdi 0x0 0
rbp 0x1 0x1
rsp 0x7fffffffdf10 0x7fffffffdf10
r8 0xf2a4f8 15901944
r9 0xf2a4f8 15901944
r10 0x0 0
r11 0x1 1
r12 0xf2a510 15901968
r13 0x7fffffffdf20 140737488346912
r14 0xf2a510 15901968
r15 0xf2a4d8 15901912
rip 0x5d3db3 0x5d3db3 <tcg_optimize+691>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
#define TCGOP_CALLI(X) (X)->param1
#define TCGOP_CALLO(X) (X)->param2
static inline const TCGHelperInfo *tcg_call_info(TCGOp *op)
{
return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1];
}
static inline unsigned tcg_call_flags(TCGOp *op)
{
return tcg_call_info(op)->flags;
}
(gdb) p *op
$1 = {opc = INDEX_op_call, param1 = 3, param2 = 1, life = 0, link = {
tqe_next = 0xf2a558, tqe_circ = {tql_next = 0xf2a558,
tql_prev = 0xf2a460}}, args = {14933928, 14933928, 14933872, 14934152,
8603936, 0, 281470681808895, 281470681808895, 281470681808895,
281470681808895, 281470681808895, 281470681808895}, output_pref = {65535,
65535}}
So tcg_call_info() return args[5] which is NULL, and tcg_call_flags()
does NULL->flags, which obviously fails with SIGSEGV.
Now what is especially interesting here is that it fails only when
the cpu does not have AVX. For example, running it under
qemu-system-x86_64 -enable-kvm -cpu Westmere fails the same way,
but with -cpu SandyBridge works. -cpu SandyBridge,-avx fails too.
I tried the same qemu-aarch64 on an actual hw system with older
CPU which does not have AVX extensions, - there, it surprizingly
works just fine.
How to debug it further?
Thanks,
/mjt
- qemu-user (arm64) fails (null ptr deref) under qemu-system-x86_64 w/o avx?,
Michael Tokarev <=