diff options
Diffstat (limited to 'meta/recipes-devtools')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/0014-linux-user-fix-to-handle-variably-sized-SIOCGSTAMP-w.patch | 339 |
2 files changed, 340 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc index e503aa866d..ecf13dc78a 100644 --- a/meta/recipes-devtools/qemu/qemu.inc +++ b/meta/recipes-devtools/qemu/qemu.inc | |||
@@ -30,6 +30,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \ | |||
30 | file://0018-fix-CVE-2018-20191.patch \ | 30 | file://0018-fix-CVE-2018-20191.patch \ |
31 | file://0019-fix-CVE-2018-20216.patch \ | 31 | file://0019-fix-CVE-2018-20216.patch \ |
32 | file://CVE-2019-3812.patch \ | 32 | file://CVE-2019-3812.patch \ |
33 | file://0014-linux-user-fix-to-handle-variably-sized-SIOCGSTAMP-w.patch \ | ||
33 | " | 34 | " |
34 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" | 35 | UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" |
35 | 36 | ||
diff --git a/meta/recipes-devtools/qemu/qemu/0014-linux-user-fix-to-handle-variably-sized-SIOCGSTAMP-w.patch b/meta/recipes-devtools/qemu/qemu/0014-linux-user-fix-to-handle-variably-sized-SIOCGSTAMP-w.patch new file mode 100644 index 0000000000..f7939b84bf --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0014-linux-user-fix-to-handle-variably-sized-SIOCGSTAMP-w.patch | |||
@@ -0,0 +1,339 @@ | |||
1 | From 8104018ba4c66e568d2583a3a0ee940851ee7471 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daniel P. Berrangé <berrange@redhat.com> | ||
3 | Date: Tue, 23 Jul 2019 17:50:00 +0200 | ||
4 | Subject: [PATCH] linux-user: fix to handle variably sized SIOCGSTAMP with new | ||
5 | kernels | ||
6 | MIME-Version: 1.0 | ||
7 | Content-Type: text/plain; charset=UTF-8 | ||
8 | Content-Transfer-Encoding: 8bit | ||
9 | |||
10 | The SIOCGSTAMP symbol was previously defined in the | ||
11 | asm-generic/sockios.h header file. QEMU sees that header | ||
12 | indirectly via sys/socket.h | ||
13 | |||
14 | In linux kernel commit 0768e17073dc527ccd18ed5f96ce85f9985e9115 | ||
15 | the asm-generic/sockios.h header no longer defines SIOCGSTAMP. | ||
16 | Instead it provides only SIOCGSTAMP_OLD, which only uses a | ||
17 | 32-bit time_t on 32-bit architectures. | ||
18 | |||
19 | The linux/sockios.h header then defines SIOCGSTAMP using | ||
20 | either SIOCGSTAMP_OLD or SIOCGSTAMP_NEW as appropriate. If | ||
21 | SIOCGSTAMP_NEW is used, then the tv_sec field is 64-bit even | ||
22 | on 32-bit architectures | ||
23 | |||
24 | To cope with this we must now convert the old and new type from | ||
25 | the target to the host one. | ||
26 | |||
27 | Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> | ||
28 | Signed-off-by: Laurent Vivier <laurent@vivier.eu> | ||
29 | Reviewed-by: Arnd Bergmann <arnd@arndb.de> | ||
30 | Message-Id: <20190718130641.15294-1-laurent@vivier.eu> | ||
31 | Signed-off-by: Laurent Vivier <laurent@vivier.eu> | ||
32 | Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> | ||
33 | --- | ||
34 | Uptream-status: Backport (upstream commit: 6d5d5dde9adb5acb32e6b8e3dfbf47fff0f308d2) | ||
35 | |||
36 | linux-user/ioctls.h | 21 +++++- | ||
37 | linux-user/syscall.c | 140 +++++++++++++++++++++++++++++-------- | ||
38 | linux-user/syscall_defs.h | 30 +++++++- | ||
39 | linux-user/syscall_types.h | 6 -- | ||
40 | 4 files changed, 159 insertions(+), 38 deletions(-) | ||
41 | |||
42 | diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h | ||
43 | index ae8951625f..e6a27ad9d6 100644 | ||
44 | --- a/linux-user/ioctls.h | ||
45 | +++ b/linux-user/ioctls.h | ||
46 | @@ -219,8 +219,25 @@ | ||
47 | IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) | ||
48 | IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) | ||
49 | IOCTL(SIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) /* pid_t */ | ||
50 | - IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval))) | ||
51 | - IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec))) | ||
52 | + | ||
53 | + /* | ||
54 | + * We can't use IOCTL_SPECIAL() because it will set | ||
55 | + * host_cmd to XXX_OLD and XXX_NEW and these macros | ||
56 | + * are not defined with kernel prior to 5.2. | ||
57 | + * We must set host_cmd to the same value as in target_cmd | ||
58 | + * otherwise the consistency check in syscall_init() | ||
59 | + * will trigger an error. | ||
60 | + * host_cmd is ignored by the do_ioctl_XXX() helpers. | ||
61 | + * FIXME: create a macro to define this kind of entry | ||
62 | + */ | ||
63 | + { TARGET_SIOCGSTAMP_OLD, TARGET_SIOCGSTAMP_OLD, | ||
64 | + "SIOCGSTAMP_OLD", IOC_R, do_ioctl_SIOCGSTAMP }, | ||
65 | + { TARGET_SIOCGSTAMPNS_OLD, TARGET_SIOCGSTAMPNS_OLD, | ||
66 | + "SIOCGSTAMPNS_OLD", IOC_R, do_ioctl_SIOCGSTAMPNS }, | ||
67 | + { TARGET_SIOCGSTAMP_NEW, TARGET_SIOCGSTAMP_NEW, | ||
68 | + "SIOCGSTAMP_NEW", IOC_R, do_ioctl_SIOCGSTAMP }, | ||
69 | + { TARGET_SIOCGSTAMPNS_NEW, TARGET_SIOCGSTAMPNS_NEW, | ||
70 | + "SIOCGSTAMPNS_NEW", IOC_R, do_ioctl_SIOCGSTAMPNS }, | ||
71 | |||
72 | IOCTL(RNDGETENTCNT, IOC_R, MK_PTR(TYPE_INT)) | ||
73 | IOCTL(RNDADDTOENTCNT, IOC_W, MK_PTR(TYPE_INT)) | ||
74 | diff --git a/linux-user/syscall.c b/linux-user/syscall.c | ||
75 | index 96cd4bf86d..6df480e13d 100644 | ||
76 | --- a/linux-user/syscall.c | ||
77 | +++ b/linux-user/syscall.c | ||
78 | @@ -37,6 +37,7 @@ | ||
79 | #include <sched.h> | ||
80 | #include <sys/timex.h> | ||
81 | #include <sys/socket.h> | ||
82 | +#include <linux/sockios.h> | ||
83 | #include <sys/un.h> | ||
84 | #include <sys/uio.h> | ||
85 | #include <poll.h> | ||
86 | @@ -1139,8 +1140,9 @@ static inline abi_long copy_from_user_timeval(struct timeval *tv, | ||
87 | { | ||
88 | struct target_timeval *target_tv; | ||
89 | |||
90 | - if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) | ||
91 | + if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) { | ||
92 | return -TARGET_EFAULT; | ||
93 | + } | ||
94 | |||
95 | __get_user(tv->tv_sec, &target_tv->tv_sec); | ||
96 | __get_user(tv->tv_usec, &target_tv->tv_usec); | ||
97 | @@ -1155,8 +1157,26 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | ||
98 | { | ||
99 | struct target_timeval *target_tv; | ||
100 | |||
101 | - if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) | ||
102 | + if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) { | ||
103 | + return -TARGET_EFAULT; | ||
104 | + } | ||
105 | + | ||
106 | + __put_user(tv->tv_sec, &target_tv->tv_sec); | ||
107 | + __put_user(tv->tv_usec, &target_tv->tv_usec); | ||
108 | + | ||
109 | + unlock_user_struct(target_tv, target_tv_addr, 1); | ||
110 | + | ||
111 | + return 0; | ||
112 | +} | ||
113 | + | ||
114 | +static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr, | ||
115 | + const struct timeval *tv) | ||
116 | +{ | ||
117 | + struct target__kernel_sock_timeval *target_tv; | ||
118 | + | ||
119 | + if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) { | ||
120 | return -TARGET_EFAULT; | ||
121 | + } | ||
122 | |||
123 | __put_user(tv->tv_sec, &target_tv->tv_sec); | ||
124 | __put_user(tv->tv_usec, &target_tv->tv_usec); | ||
125 | @@ -1166,6 +1186,48 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | +static inline abi_long target_to_host_timespec(struct timespec *host_ts, | ||
130 | + abi_ulong target_addr) | ||
131 | +{ | ||
132 | + struct target_timespec *target_ts; | ||
133 | + | ||
134 | + if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) { | ||
135 | + return -TARGET_EFAULT; | ||
136 | + } | ||
137 | + __get_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
138 | + __get_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
139 | + unlock_user_struct(target_ts, target_addr, 0); | ||
140 | + return 0; | ||
141 | +} | ||
142 | + | ||
143 | +static inline abi_long host_to_target_timespec(abi_ulong target_addr, | ||
144 | + struct timespec *host_ts) | ||
145 | +{ | ||
146 | + struct target_timespec *target_ts; | ||
147 | + | ||
148 | + if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) { | ||
149 | + return -TARGET_EFAULT; | ||
150 | + } | ||
151 | + __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
152 | + __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
153 | + unlock_user_struct(target_ts, target_addr, 1); | ||
154 | + return 0; | ||
155 | +} | ||
156 | + | ||
157 | +static inline abi_long host_to_target_timespec64(abi_ulong target_addr, | ||
158 | + struct timespec *host_ts) | ||
159 | +{ | ||
160 | + struct target__kernel_timespec *target_ts; | ||
161 | + | ||
162 | + if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) { | ||
163 | + return -TARGET_EFAULT; | ||
164 | + } | ||
165 | + __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
166 | + __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
167 | + unlock_user_struct(target_ts, target_addr, 1); | ||
168 | + return 0; | ||
169 | +} | ||
170 | + | ||
171 | static inline abi_long copy_from_user_timezone(struct timezone *tz, | ||
172 | abi_ulong target_tz_addr) | ||
173 | { | ||
174 | @@ -4790,6 +4852,54 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
175 | return get_errno(safe_ioctl(fd, ie->host_cmd, sig)); | ||
176 | } | ||
177 | |||
178 | +static abi_long do_ioctl_SIOCGSTAMP(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
179 | + int fd, int cmd, abi_long arg) | ||
180 | +{ | ||
181 | + struct timeval tv; | ||
182 | + abi_long ret; | ||
183 | + | ||
184 | + ret = get_errno(safe_ioctl(fd, SIOCGSTAMP, &tv)); | ||
185 | + if (is_error(ret)) { | ||
186 | + return ret; | ||
187 | + } | ||
188 | + | ||
189 | + if (cmd == (int)TARGET_SIOCGSTAMP_OLD) { | ||
190 | + if (copy_to_user_timeval(arg, &tv)) { | ||
191 | + return -TARGET_EFAULT; | ||
192 | + } | ||
193 | + } else { | ||
194 | + if (copy_to_user_timeval64(arg, &tv)) { | ||
195 | + return -TARGET_EFAULT; | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | + return ret; | ||
200 | +} | ||
201 | + | ||
202 | +static abi_long do_ioctl_SIOCGSTAMPNS(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
203 | + int fd, int cmd, abi_long arg) | ||
204 | +{ | ||
205 | + struct timespec ts; | ||
206 | + abi_long ret; | ||
207 | + | ||
208 | + ret = get_errno(safe_ioctl(fd, SIOCGSTAMPNS, &ts)); | ||
209 | + if (is_error(ret)) { | ||
210 | + return ret; | ||
211 | + } | ||
212 | + | ||
213 | + if (cmd == (int)TARGET_SIOCGSTAMPNS_OLD) { | ||
214 | + if (host_to_target_timespec(arg, &ts)) { | ||
215 | + return -TARGET_EFAULT; | ||
216 | + } | ||
217 | + } else{ | ||
218 | + if (host_to_target_timespec64(arg, &ts)) { | ||
219 | + return -TARGET_EFAULT; | ||
220 | + } | ||
221 | + } | ||
222 | + | ||
223 | + return ret; | ||
224 | +} | ||
225 | + | ||
226 | #ifdef TIOCGPTPEER | ||
227 | static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp, | ||
228 | int fd, int cmd, abi_long arg) | ||
229 | @@ -6160,32 +6270,6 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, | ||
230 | } | ||
231 | #endif | ||
232 | |||
233 | -static inline abi_long target_to_host_timespec(struct timespec *host_ts, | ||
234 | - abi_ulong target_addr) | ||
235 | -{ | ||
236 | - struct target_timespec *target_ts; | ||
237 | - | ||
238 | - if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) | ||
239 | - return -TARGET_EFAULT; | ||
240 | - __get_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
241 | - __get_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
242 | - unlock_user_struct(target_ts, target_addr, 0); | ||
243 | - return 0; | ||
244 | -} | ||
245 | - | ||
246 | -static inline abi_long host_to_target_timespec(abi_ulong target_addr, | ||
247 | - struct timespec *host_ts) | ||
248 | -{ | ||
249 | - struct target_timespec *target_ts; | ||
250 | - | ||
251 | - if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) | ||
252 | - return -TARGET_EFAULT; | ||
253 | - __put_user(host_ts->tv_sec, &target_ts->tv_sec); | ||
254 | - __put_user(host_ts->tv_nsec, &target_ts->tv_nsec); | ||
255 | - unlock_user_struct(target_ts, target_addr, 1); | ||
256 | - return 0; | ||
257 | -} | ||
258 | - | ||
259 | static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec, | ||
260 | abi_ulong target_addr) | ||
261 | { | ||
262 | diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h | ||
263 | index 12c8407144..c918419306 100644 | ||
264 | --- a/linux-user/syscall_defs.h | ||
265 | +++ b/linux-user/syscall_defs.h | ||
266 | @@ -208,16 +208,34 @@ struct target_linger { | ||
267 | abi_int l_linger; /* How long to linger for */ | ||
268 | }; | ||
269 | |||
270 | +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) | ||
271 | +struct target_timeval { | ||
272 | + abi_long tv_sec; | ||
273 | + abi_int tv_usec; | ||
274 | +}; | ||
275 | +#define target__kernel_sock_timeval target_timeval | ||
276 | +#else | ||
277 | struct target_timeval { | ||
278 | abi_long tv_sec; | ||
279 | abi_long tv_usec; | ||
280 | }; | ||
281 | |||
282 | +struct target__kernel_sock_timeval { | ||
283 | + abi_llong tv_sec; | ||
284 | + abi_llong tv_usec; | ||
285 | +}; | ||
286 | +#endif | ||
287 | + | ||
288 | struct target_timespec { | ||
289 | abi_long tv_sec; | ||
290 | abi_long tv_nsec; | ||
291 | }; | ||
292 | |||
293 | +struct target__kernel_timespec { | ||
294 | + abi_llong tv_sec; | ||
295 | + abi_llong tv_nsec; | ||
296 | +}; | ||
297 | + | ||
298 | struct target_timezone { | ||
299 | abi_int tz_minuteswest; | ||
300 | abi_int tz_dsttime; | ||
301 | @@ -743,8 +761,16 @@ struct target_pollfd { | ||
302 | #define TARGET_SIOCATMARK 0x8905 | ||
303 | #define TARGET_SIOCGPGRP 0x8904 | ||
304 | #endif | ||
305 | -#define TARGET_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ | ||
306 | -#define TARGET_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ | ||
307 | +#if defined(TARGET_SH4) | ||
308 | +#define TARGET_SIOCGSTAMP_OLD TARGET_IOR('s', 100, struct target_timeval) | ||
309 | +#define TARGET_SIOCGSTAMPNS_OLD TARGET_IOR('s', 101, struct target_timespec) | ||
310 | +#else | ||
311 | +#define TARGET_SIOCGSTAMP_OLD 0x8906 | ||
312 | +#define TARGET_SIOCGSTAMPNS_OLD 0x8907 | ||
313 | +#endif | ||
314 | + | ||
315 | +#define TARGET_SIOCGSTAMP_NEW TARGET_IOR(0x89, 0x06, abi_llong[2]) | ||
316 | +#define TARGET_SIOCGSTAMPNS_NEW TARGET_IOR(0x89, 0x07, abi_llong[2]) | ||
317 | |||
318 | /* Networking ioctls */ | ||
319 | #define TARGET_SIOCADDRT 0x890B /* add routing table entry */ | ||
320 | diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h | ||
321 | index b98a23b0f1..4e36983826 100644 | ||
322 | --- a/linux-user/syscall_types.h | ||
323 | +++ b/linux-user/syscall_types.h | ||
324 | @@ -14,12 +14,6 @@ STRUCT(serial_icounter_struct, | ||
325 | STRUCT(sockaddr, | ||
326 | TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14)) | ||
327 | |||
328 | -STRUCT(timeval, | ||
329 | - MK_ARRAY(TYPE_LONG, 2)) | ||
330 | - | ||
331 | -STRUCT(timespec, | ||
332 | - MK_ARRAY(TYPE_LONG, 2)) | ||
333 | - | ||
334 | STRUCT(rtentry, | ||
335 | TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), | ||
336 | TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, TYPE_PTRVOID, | ||
337 | -- | ||
338 | 2.21.0 | ||
339 | |||