diff options
| author | Christian Krinitsin <mail@krinitsin.com> | 2025-07-05 20:00:38 +0200 |
|---|---|---|
| committer | Christian Krinitsin <mail@krinitsin.com> | 2025-07-05 20:00:38 +0200 |
| commit | 96049c939b1916d80532630d63c14e04d5244f1d (patch) | |
| tree | 7fb9df428f074078e714f1e038210cdff887185a /results/classifier/user-mode-bugs/1774149 | |
| parent | 40bbb77d4dfebff4f99c2f90b2c0db737b0ecc5a (diff) | |
| download | qemu-analysis-96049c939b1916d80532630d63c14e04d5244f1d.tar.gz qemu-analysis-96049c939b1916d80532630d63c14e04d5244f1d.zip | |
lock user-mode and semantic-bugs
Diffstat (limited to 'results/classifier/user-mode-bugs/1774149')
| -rw-r--r-- | results/classifier/user-mode-bugs/1774149 | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/results/classifier/user-mode-bugs/1774149 b/results/classifier/user-mode-bugs/1774149 new file mode 100644 index 000000000..c0a07c031 --- /dev/null +++ b/results/classifier/user-mode-bugs/1774149 @@ -0,0 +1,78 @@ + + +qemu-user x86_64 x86 gdb call function from gdb doesn't work + +While running qemu user x86_64 x86 with gdb server, calling functions are not working. + +Here is how to reproduce it: + +run in a terminal: +$ qemu-x86_64 -g 12345 -L / /bin/ls + +In another terminal run gdb: +(gdb) file /bin/ls +(gdb) target remote :12345 +(gdb) b _init +(gdb) c +(gdb) call malloc(1) +Could not fetch register "fs_base"; remote failure reply 'E14' + +In other cases we also got the error: +Could not fetch register "orig_rax"; remote failure reply 'E14' + +Here is how I patched it (it is only a workaround): + +diff --git a/gdbstub.c b/gdbstub.c +index 2a94030..5749efe 100644 +--- a/gdbstub.c ++++ b/gdbstub.c +@@ -668,6 +668,11 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) + return r->get_reg(env, mem_buf, reg - r->base_reg); + } + } ++#ifdef TARGET_X86_64 ++ return 8; ++#elif TARGET_I386 ++ return 4; ++#endif + return 0; + } + +(Our guess for this issue was, gdb is requesting for 'fake' registers to know register size) + +Once we patched that, we got another problem while calling functions from gdb: We could call functions, but only once. + +Here is how to reproduce it: +run in a terminal: +$ qemu-x86_64 -g 12345 -L / /bin/ls + +In another terminal run gdb: +(gdb) file /bin/ls +(gdb) target remote :12345 +(gdb) b _init +(gdb) c +(gdb) call malloc(1) +$1 = (void *) 0x620010 +(gdb) call malloc(1) +Cannot access memory at address 0x40007ffb8f + +Here is how we patched it to make it work: + +diff --git a/exec.c b/exec.c +index 03238a3..d303922 100644 +--- a/exec.c ++++ b/exec.c +@@ -2833,7 +2833,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, + if (!(flags & PAGE_VALID)) + return -1; + if (is_write) { +- if (!(flags & PAGE_WRITE)) ++ if (!(flags & (PAGE_WRITE | PAGE_WRITE_ORG))) + return -1; + /* XXX: this code should not depend on lock_user */ + if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) + +From what we saw, there is a page which is passed to read-only after first execution, and gdb need to write on that page to put a breakpoint. (on the stack) + +We suspect this is linked to this: +https://qemu.weilnetz.de/w64/2012/2012-06-28/qemu-tech.html#Self_002dmodifying-code-and-translated-code-invalidation \ No newline at end of file |