diff options
Diffstat (limited to 'gitlab/issues/target_i386/host_missing/accel_missing/1648.toml')
| -rw-r--r-- | gitlab/issues/target_i386/host_missing/accel_missing/1648.toml | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gitlab/issues/target_i386/host_missing/accel_missing/1648.toml b/gitlab/issues/target_i386/host_missing/accel_missing/1648.toml new file mode 100644 index 000000000..427b65295 --- /dev/null +++ b/gitlab/issues/target_i386/host_missing/accel_missing/1648.toml @@ -0,0 +1,70 @@ +id = 1648 +title = "linux-user: incorrect alignment of sigframe::pretcode & rt_sigframe::pretcode cause crash" +state = "closed" +created_at = "2023-05-12T15:26:57.371Z" +closed_at = "2024-05-27T02:33:45.506Z" +labels = ["Closed::Fixed", "kind::Bug", "linux-user", "target: i386"] +url = "https://gitlab.com/qemu-project/qemu/-/issues/1648" +host-os = "Windows 11" +host-arch = "x86_64" +qemu-version = "8.0.0" +guest-os = "n/a" +guest-arch = "n/a" +description = """Corrent Print Result: + +sp: cdd3b4e8 + +SUCCEEDED! + +qemu-x86_64 Print Result: + +sp: 2804170 + +qemu: uncaught target signal 11 (Segmentation fault) - core dumped + +Segmentation fault + +Reason of Bug: + +sigframe::pretcode & rt_sigframe::pretcode must align of 16n-sizeof(void*) instead of 16n, Because rsp align of 16n before instruction "call" in caller, After "call", push address of "call" in caller. sp of begin in callee is 16n-sizeof(void*) + +For example on x86_64: + +reference to "qemu/linux-user/i386/signal.c" + +``` +# define TARGET_FPSTATE_FXSAVE_OFFSET 0 + +struct rt_sigframe { + abi_ulong pretcode; + struct target_ucontext uc; + struct target_siginfo info; + struct target_fpstate fpstate QEMU_ALIGNED(16); +}; +#define TARGET_RT_SIGFRAME_FXSAVE_OFFSET ( \\ + offsetof(struct rt_sigframe, fpstate) + TARGET_FPSTATE_FXSAVE_OFFSET) +``` + +offsetof(struct rt_sigframe, fpstate) align of 16 + +TARGET_FPSTATE_FXSAVE_OFFSET is 0 + +TARGET_RT_SIGFRAME_FXSAVE_OFFSET is 16n, also alignment of fxsave is 64 + +so address of rt_sigframe::pretcode is 16n instead of 16n - sizeof(void*), It is incorect! + +Fix the bug: + +``` +struct rt_sigframe { + abi_ulong pretcode; + struct target_ucontext uc; + struct target_siginfo info; + abi_ulong unused QEMU_ALIGNED(16); + struct target_fpstate fpstate; +}; +``` + +offsetof(struct rt_sigframe, fpstate) is 16n+8, so address of rt_sigframe::pretcode is 16n-8 on x86_64.""" +reproduce = "n/a" +additional = "n/a" |