summary refs log tree commit diff stats
path: root/results/classifier/zero-shot/118/all/1857640
blob: 7ccf7def51bfaea19d507a7a3896be32fd867b07 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
peripherals: 0.966
graphic: 0.959
mistranslation: 0.958
permissions: 0.957
debug: 0.952
socket: 0.950
performance: 0.950
user-level: 0.948
register: 0.947
risc-v: 0.945
PID: 0.937
device: 0.935
x86: 0.929
architecture: 0.927
kernel: 0.925
virtual: 0.925
network: 0.923
ppc: 0.920
arm: 0.919
assembly: 0.917
i386: 0.916
semantic: 0.904
boot: 0.902
files: 0.901
hypervisor: 0.892
vnc: 0.887
KVM: 0.844
TCG: 0.844
VMM: 0.760

qemu-system-i386 registers clobbered after gdb set due to k_gs_base bug in gdbstub

Due to a bug in /target/i386/gdbstub.c, setting registers in gdb causes the ones following k_gs_base to get clobbered.  

I'm using qemu version 4.2.50 on an msys64 and start qemu's i386 with a gdb server.

$ qemu-system-i386 -version
QEMU emulator version 4.2.50 (v4.2.0-363-gdd5b0f9549-dirty)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

$ qemu-system-i386 -gdb tcp::29096 -S
C:\msys64\usr\local\qemu-system-i386.exe: invalid accelerator kvm
C:\msys64\usr\local\qemu-system-i386.exe: falling back to tcg


I start a gdb client, connect to the server, display the register state, set k_gs_base, display the register state again, and notice an issue. (Setting other registers also clobbers the ones after k_gs_base).

$ gdb -q
(gdb) target remote :29096
...
(gdb) info regs
...
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x60000010       [ CD NW ET ]
cr2            0x0      0
...
(gdb) set $k_gs_base = 0x41414141
(gdb) info regs
...
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x41414151       [ CD WP ET PE ]
cr2            0x60000010       1610612752
...


In the gdbstub code, I notice that the read and write functions are not symmetric for IDX_SEG_REGS + 8, which corresponds to k_gs_base.

$ cat /usr/local/src/qemu-4.2.0/target/i386/gdbstub.c
...
int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
...
        case IDX_SEG_REGS + 8:
#ifdef TARGET_X86_64
            if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
                return gdb_get_reg64(mem_buf, env->kernelgsbase);
            }
            return gdb_get_reg32(mem_buf, env->kernelgsbase);
#else
            return gdb_get_reg32(mem_buf, 0);
#endif
...
}
...
int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
...
#ifdef TARGET_X86_64
        case IDX_SEG_REGS + 8:
            if (env->hflags & HF_CS64_MASK) {
                env->kernelgsbase = ldq_p(mem_buf);
                return 8;
            }
            env->kernelgsbase = ldl_p(mem_buf);
            return 4;
#endif
...
}
...


I change the write function, rebuild, and verify that the issue is resolved.

$ cat /usr/local/src/qemu-4.2.0/target/i386/gdbstub.c
int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
...
        case IDX_SEG_REGS + 8:
#ifdef TARGET_X86_64
            if (env->hflags & HF_CS64_MASK) {
                env->kernelgsbase = ldq_p(mem_buf);
                return 8;
            }
            env->kernelgsbase = ldl_p(mem_buf);
            return 4;
#else
            return 4;
#endif
...
}
...

$ make
...
$ make install
...

$ qemu-system-i386 -gdb tcp::29096 -S

$ gdb -q
(gdb) target remote :29096
...
(gdb) info regs
...
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x60000010       [ CD NW ET ]
cr2            0x0      0
...
(gdb) set $k_gs_base = 0x41414141
(gdb) info regs
...
gs_base        0x0      0
k_gs_base      0x0      0
cr0            0x60000010       [ CD NW ET ]
cr2            0x0      0
...


I'll submit the patch below.

$ diff gdbstub.c gdbstub.c.bkp
353d352
<         case IDX_SEG_REGS + 8:
354a354
>         case IDX_SEG_REGS + 8:
362,363d361
< #else
<             return 4;

Fixed here:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=5a07192a042e