1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_COMPAT_H |
3 | #define _LINUX_COMPAT_H |
4 | /* |
5 | * These are the type definitions for the architecture specific |
6 | * syscall compatibility layer. |
7 | */ |
8 | |
9 | #include <linux/types.h> |
10 | #include <linux/time.h> |
11 | |
12 | #include <linux/stat.h> |
13 | #include <linux/param.h> /* for HZ */ |
14 | #include <linux/sem.h> |
15 | #include <linux/socket.h> |
16 | #include <linux/if.h> |
17 | #include <linux/fs.h> |
18 | #include <linux/aio_abi.h> /* for aio_context_t */ |
19 | #include <linux/uaccess.h> |
20 | #include <linux/unistd.h> |
21 | |
22 | #include <asm/compat.h> |
23 | #include <asm/siginfo.h> |
24 | #include <asm/signal.h> |
25 | |
26 | #ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER |
27 | /* |
28 | * It may be useful for an architecture to override the definitions of the |
29 | * COMPAT_SYSCALL_DEFINE0 and COMPAT_SYSCALL_DEFINEx() macros, in particular |
30 | * to use a different calling convention for syscalls. To allow for that, |
31 | + the prototypes for the compat_sys_*() functions below will *not* be included |
32 | * if CONFIG_ARCH_HAS_SYSCALL_WRAPPER is enabled. |
33 | */ |
34 | #include <asm/syscall_wrapper.h> |
35 | #endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */ |
36 | |
37 | #ifndef COMPAT_USE_64BIT_TIME |
38 | #define COMPAT_USE_64BIT_TIME 0 |
39 | #endif |
40 | |
41 | #ifndef __SC_DELOUSE |
42 | #define __SC_DELOUSE(t,v) ((__force t)(unsigned long)(v)) |
43 | #endif |
44 | |
45 | #ifndef COMPAT_SYSCALL_DEFINE0 |
46 | #define COMPAT_SYSCALL_DEFINE0(name) \ |
47 | asmlinkage long compat_sys_##name(void); \ |
48 | ALLOW_ERROR_INJECTION(compat_sys_##name, ERRNO); \ |
49 | asmlinkage long compat_sys_##name(void) |
50 | #endif /* COMPAT_SYSCALL_DEFINE0 */ |
51 | |
52 | #define COMPAT_SYSCALL_DEFINE1(name, ...) \ |
53 | COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) |
54 | #define COMPAT_SYSCALL_DEFINE2(name, ...) \ |
55 | COMPAT_SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) |
56 | #define COMPAT_SYSCALL_DEFINE3(name, ...) \ |
57 | COMPAT_SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) |
58 | #define COMPAT_SYSCALL_DEFINE4(name, ...) \ |
59 | COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) |
60 | #define COMPAT_SYSCALL_DEFINE5(name, ...) \ |
61 | COMPAT_SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) |
62 | #define COMPAT_SYSCALL_DEFINE6(name, ...) \ |
63 | COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) |
64 | |
65 | /* |
66 | * The asmlinkage stub is aliased to a function named __se_compat_sys_*() which |
67 | * sign-extends 32-bit ints to longs whenever needed. The actual work is |
68 | * done within __do_compat_sys_*(). |
69 | */ |
70 | #ifndef COMPAT_SYSCALL_DEFINEx |
71 | #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ |
72 | __diag_push(); \ |
73 | __diag_ignore(GCC, 8, "-Wattribute-alias", \ |
74 | "Type aliasing is used to sanitize syscall arguments");\ |
75 | asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ |
76 | __attribute__((alias(__stringify(__se_compat_sys##name)))); \ |
77 | ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \ |
78 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ |
79 | asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ |
80 | asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ |
81 | { \ |
82 | long ret = __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));\ |
83 | __MAP(x,__SC_TEST,__VA_ARGS__); \ |
84 | return ret; \ |
85 | } \ |
86 | __diag_pop(); \ |
87 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) |
88 | #endif /* COMPAT_SYSCALL_DEFINEx */ |
89 | |
90 | struct compat_iovec { |
91 | compat_uptr_t iov_base; |
92 | compat_size_t iov_len; |
93 | }; |
94 | |
95 | #ifndef compat_user_stack_pointer |
96 | #define compat_user_stack_pointer() current_user_stack_pointer() |
97 | #endif |
98 | #ifndef compat_sigaltstack /* we'll need that for MIPS */ |
99 | typedef struct compat_sigaltstack { |
100 | compat_uptr_t ss_sp; |
101 | int ss_flags; |
102 | compat_size_t ss_size; |
103 | } compat_stack_t; |
104 | #endif |
105 | #ifndef COMPAT_MINSIGSTKSZ |
106 | #define COMPAT_MINSIGSTKSZ MINSIGSTKSZ |
107 | #endif |
108 | |
109 | #define compat_jiffies_to_clock_t(x) \ |
110 | (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) |
111 | |
112 | typedef __compat_uid32_t compat_uid_t; |
113 | typedef __compat_gid32_t compat_gid_t; |
114 | |
115 | struct compat_sel_arg_struct; |
116 | struct rusage; |
117 | |
118 | struct old_itimerval32; |
119 | |
120 | struct compat_tms { |
121 | compat_clock_t tms_utime; |
122 | compat_clock_t tms_stime; |
123 | compat_clock_t tms_cutime; |
124 | compat_clock_t tms_cstime; |
125 | }; |
126 | |
127 | #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) |
128 | |
129 | typedef struct { |
130 | compat_sigset_word sig[_COMPAT_NSIG_WORDS]; |
131 | } compat_sigset_t; |
132 | |
133 | int set_compat_user_sigmask(const compat_sigset_t __user *umask, |
134 | size_t sigsetsize); |
135 | |
136 | struct compat_sigaction { |
137 | #ifndef __ARCH_HAS_IRIX_SIGACTION |
138 | compat_uptr_t sa_handler; |
139 | compat_ulong_t sa_flags; |
140 | #else |
141 | compat_uint_t sa_flags; |
142 | compat_uptr_t sa_handler; |
143 | #endif |
144 | #ifdef __ARCH_HAS_SA_RESTORER |
145 | compat_uptr_t sa_restorer; |
146 | #endif |
147 | compat_sigset_t sa_mask __packed; |
148 | }; |
149 | |
150 | typedef union compat_sigval { |
151 | compat_int_t sival_int; |
152 | compat_uptr_t sival_ptr; |
153 | } compat_sigval_t; |
154 | |
155 | typedef struct compat_siginfo { |
156 | int si_signo; |
157 | #ifndef __ARCH_HAS_SWAPPED_SIGINFO |
158 | int si_errno; |
159 | int si_code; |
160 | #else |
161 | int si_code; |
162 | int si_errno; |
163 | #endif |
164 | |
165 | union { |
166 | int _pad[128/sizeof(int) - 3]; |
167 | |
168 | /* kill() */ |
169 | struct { |
170 | compat_pid_t _pid; /* sender's pid */ |
171 | __compat_uid32_t _uid; /* sender's uid */ |
172 | } _kill; |
173 | |
174 | /* POSIX.1b timers */ |
175 | struct { |
176 | compat_timer_t _tid; /* timer id */ |
177 | int _overrun; /* overrun count */ |
178 | compat_sigval_t _sigval; /* same as below */ |
179 | } _timer; |
180 | |
181 | /* POSIX.1b signals */ |
182 | struct { |
183 | compat_pid_t _pid; /* sender's pid */ |
184 | __compat_uid32_t _uid; /* sender's uid */ |
185 | compat_sigval_t _sigval; |
186 | } _rt; |
187 | |
188 | /* SIGCHLD */ |
189 | struct { |
190 | compat_pid_t _pid; /* which child */ |
191 | __compat_uid32_t _uid; /* sender's uid */ |
192 | int _status; /* exit code */ |
193 | compat_clock_t _utime; |
194 | compat_clock_t _stime; |
195 | } _sigchld; |
196 | |
197 | #ifdef CONFIG_X86_X32_ABI |
198 | /* SIGCHLD (x32 version) */ |
199 | struct { |
200 | compat_pid_t _pid; /* which child */ |
201 | __compat_uid32_t _uid; /* sender's uid */ |
202 | int _status; /* exit code */ |
203 | compat_s64 _utime; |
204 | compat_s64 _stime; |
205 | } _sigchld_x32; |
206 | #endif |
207 | |
208 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ |
209 | struct { |
210 | compat_uptr_t _addr; /* faulting insn/memory ref. */ |
211 | #define __COMPAT_ADDR_BND_PKEY_PAD (__alignof__(compat_uptr_t) < sizeof(short) ? \ |
212 | sizeof(short) : __alignof__(compat_uptr_t)) |
213 | union { |
214 | /* used on alpha and sparc */ |
215 | int _trapno; /* TRAP # which caused the signal */ |
216 | /* |
217 | * used when si_code=BUS_MCEERR_AR or |
218 | * used when si_code=BUS_MCEERR_AO |
219 | */ |
220 | short int _addr_lsb; /* Valid LSB of the reported address. */ |
221 | /* used when si_code=SEGV_BNDERR */ |
222 | struct { |
223 | char _dummy_bnd[__COMPAT_ADDR_BND_PKEY_PAD]; |
224 | compat_uptr_t _lower; |
225 | compat_uptr_t _upper; |
226 | } _addr_bnd; |
227 | /* used when si_code=SEGV_PKUERR */ |
228 | struct { |
229 | char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD]; |
230 | u32 _pkey; |
231 | } _addr_pkey; |
232 | /* used when si_code=TRAP_PERF */ |
233 | struct { |
234 | compat_ulong_t _data; |
235 | u32 _type; |
236 | u32 _flags; |
237 | } _perf; |
238 | }; |
239 | } _sigfault; |
240 | |
241 | /* SIGPOLL */ |
242 | struct { |
243 | compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ |
244 | int _fd; |
245 | } _sigpoll; |
246 | |
247 | struct { |
248 | compat_uptr_t _call_addr; /* calling user insn */ |
249 | int _syscall; /* triggering system call number */ |
250 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ |
251 | } _sigsys; |
252 | } _sifields; |
253 | } compat_siginfo_t; |
254 | |
255 | struct compat_rlimit { |
256 | compat_ulong_t rlim_cur; |
257 | compat_ulong_t rlim_max; |
258 | }; |
259 | |
260 | #ifdef __ARCH_NEED_COMPAT_FLOCK64_PACKED |
261 | #define __ARCH_COMPAT_FLOCK64_PACK __attribute__((packed)) |
262 | #else |
263 | #define __ARCH_COMPAT_FLOCK64_PACK |
264 | #endif |
265 | |
266 | struct compat_flock { |
267 | short l_type; |
268 | short l_whence; |
269 | compat_off_t l_start; |
270 | compat_off_t l_len; |
271 | #ifdef __ARCH_COMPAT_FLOCK_EXTRA_SYSID |
272 | __ARCH_COMPAT_FLOCK_EXTRA_SYSID |
273 | #endif |
274 | compat_pid_t l_pid; |
275 | #ifdef __ARCH_COMPAT_FLOCK_PAD |
276 | __ARCH_COMPAT_FLOCK_PAD |
277 | #endif |
278 | }; |
279 | |
280 | struct compat_flock64 { |
281 | short l_type; |
282 | short l_whence; |
283 | compat_loff_t l_start; |
284 | compat_loff_t l_len; |
285 | compat_pid_t l_pid; |
286 | #ifdef __ARCH_COMPAT_FLOCK64_PAD |
287 | __ARCH_COMPAT_FLOCK64_PAD |
288 | #endif |
289 | } __ARCH_COMPAT_FLOCK64_PACK; |
290 | |
291 | struct compat_rusage { |
292 | struct old_timeval32 ru_utime; |
293 | struct old_timeval32 ru_stime; |
294 | compat_long_t ; |
295 | compat_long_t ; |
296 | compat_long_t ; |
297 | compat_long_t ; |
298 | compat_long_t ru_minflt; |
299 | compat_long_t ru_majflt; |
300 | compat_long_t ru_nswap; |
301 | compat_long_t ru_inblock; |
302 | compat_long_t ru_oublock; |
303 | compat_long_t ru_msgsnd; |
304 | compat_long_t ru_msgrcv; |
305 | compat_long_t ru_nsignals; |
306 | compat_long_t ru_nvcsw; |
307 | compat_long_t ru_nivcsw; |
308 | }; |
309 | |
310 | extern int put_compat_rusage(const struct rusage *, |
311 | struct compat_rusage __user *); |
312 | |
313 | struct compat_siginfo; |
314 | struct __compat_aio_sigset; |
315 | |
316 | struct compat_dirent { |
317 | u32 d_ino; |
318 | compat_off_t d_off; |
319 | u16 d_reclen; |
320 | char d_name[256]; |
321 | }; |
322 | |
323 | struct compat_ustat { |
324 | compat_daddr_t f_tfree; |
325 | compat_ino_t f_tinode; |
326 | char f_fname[6]; |
327 | char f_fpack[6]; |
328 | }; |
329 | |
330 | #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) |
331 | |
332 | typedef struct compat_sigevent { |
333 | compat_sigval_t sigev_value; |
334 | compat_int_t sigev_signo; |
335 | compat_int_t sigev_notify; |
336 | union { |
337 | compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; |
338 | compat_int_t _tid; |
339 | |
340 | struct { |
341 | compat_uptr_t _function; |
342 | compat_uptr_t _attribute; |
343 | } _sigev_thread; |
344 | } _sigev_un; |
345 | } compat_sigevent_t; |
346 | |
347 | struct compat_ifmap { |
348 | compat_ulong_t mem_start; |
349 | compat_ulong_t mem_end; |
350 | unsigned short base_addr; |
351 | unsigned char irq; |
352 | unsigned char dma; |
353 | unsigned char port; |
354 | }; |
355 | |
356 | struct compat_if_settings { |
357 | unsigned int type; /* Type of physical device or protocol */ |
358 | unsigned int size; /* Size of the data allocated by the caller */ |
359 | compat_uptr_t ifs_ifsu; /* union of pointers */ |
360 | }; |
361 | |
362 | struct compat_ifreq { |
363 | union { |
364 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ |
365 | } ifr_ifrn; |
366 | union { |
367 | struct sockaddr ifru_addr; |
368 | struct sockaddr ifru_dstaddr; |
369 | struct sockaddr ifru_broadaddr; |
370 | struct sockaddr ifru_netmask; |
371 | struct sockaddr ifru_hwaddr; |
372 | short ifru_flags; |
373 | compat_int_t ifru_ivalue; |
374 | compat_int_t ifru_mtu; |
375 | struct compat_ifmap ifru_map; |
376 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ |
377 | char ifru_newname[IFNAMSIZ]; |
378 | compat_caddr_t ifru_data; |
379 | struct compat_if_settings ifru_settings; |
380 | } ifr_ifru; |
381 | }; |
382 | |
383 | struct compat_ifconf { |
384 | compat_int_t ifc_len; /* size of buffer */ |
385 | compat_caddr_t ifcbuf; |
386 | }; |
387 | |
388 | struct compat_robust_list { |
389 | compat_uptr_t next; |
390 | }; |
391 | |
392 | struct compat_robust_list_head { |
393 | struct compat_robust_list list; |
394 | compat_long_t futex_offset; |
395 | compat_uptr_t list_op_pending; |
396 | }; |
397 | |
398 | #ifdef CONFIG_COMPAT_OLD_SIGACTION |
399 | struct compat_old_sigaction { |
400 | compat_uptr_t sa_handler; |
401 | compat_old_sigset_t sa_mask; |
402 | compat_ulong_t sa_flags; |
403 | compat_uptr_t sa_restorer; |
404 | }; |
405 | #endif |
406 | |
407 | struct compat_keyctl_kdf_params { |
408 | compat_uptr_t hashname; |
409 | compat_uptr_t otherinfo; |
410 | __u32 otherinfolen; |
411 | __u32 __spare[8]; |
412 | }; |
413 | |
414 | struct compat_stat; |
415 | struct compat_statfs; |
416 | struct compat_statfs64; |
417 | struct compat_old_linux_dirent; |
418 | struct compat_linux_dirent; |
419 | struct linux_dirent64; |
420 | struct compat_msghdr; |
421 | struct compat_mmsghdr; |
422 | struct compat_sysinfo; |
423 | struct compat_sysctl_args; |
424 | struct compat_kexec_segment; |
425 | struct compat_mq_attr; |
426 | struct compat_msgbuf; |
427 | |
428 | void copy_siginfo_to_external32(struct compat_siginfo *to, |
429 | const struct kernel_siginfo *from); |
430 | int copy_siginfo_from_user32(kernel_siginfo_t *to, |
431 | const struct compat_siginfo __user *from); |
432 | int __copy_siginfo_to_user32(struct compat_siginfo __user *to, |
433 | const kernel_siginfo_t *from); |
434 | #ifndef copy_siginfo_to_user32 |
435 | #define copy_siginfo_to_user32 __copy_siginfo_to_user32 |
436 | #endif |
437 | int get_compat_sigevent(struct sigevent *event, |
438 | const struct compat_sigevent __user *u_event); |
439 | |
440 | extern int get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat); |
441 | |
442 | /* |
443 | * Defined inline such that size can be compile time constant, which avoids |
444 | * CONFIG_HARDENED_USERCOPY complaining about copies from task_struct |
445 | */ |
446 | static inline int |
447 | put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, |
448 | unsigned int size) |
449 | { |
450 | /* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */ |
451 | #if defined(__BIG_ENDIAN) && defined(CONFIG_64BIT) |
452 | compat_sigset_t v; |
453 | switch (_NSIG_WORDS) { |
454 | case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3]; |
455 | fallthrough; |
456 | case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2]; |
457 | fallthrough; |
458 | case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1]; |
459 | fallthrough; |
460 | case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0]; |
461 | } |
462 | return copy_to_user(compat, &v, size) ? -EFAULT : 0; |
463 | #else |
464 | return copy_to_user(to: compat, from: set, n: size) ? -EFAULT : 0; |
465 | #endif |
466 | } |
467 | |
468 | #ifdef CONFIG_CPU_BIG_ENDIAN |
469 | #define unsafe_put_compat_sigset(compat, set, label) do { \ |
470 | compat_sigset_t __user *__c = compat; \ |
471 | const sigset_t *__s = set; \ |
472 | \ |
473 | switch (_NSIG_WORDS) { \ |
474 | case 4: \ |
475 | unsafe_put_user(__s->sig[3] >> 32, &__c->sig[7], label); \ |
476 | unsafe_put_user(__s->sig[3], &__c->sig[6], label); \ |
477 | fallthrough; \ |
478 | case 3: \ |
479 | unsafe_put_user(__s->sig[2] >> 32, &__c->sig[5], label); \ |
480 | unsafe_put_user(__s->sig[2], &__c->sig[4], label); \ |
481 | fallthrough; \ |
482 | case 2: \ |
483 | unsafe_put_user(__s->sig[1] >> 32, &__c->sig[3], label); \ |
484 | unsafe_put_user(__s->sig[1], &__c->sig[2], label); \ |
485 | fallthrough; \ |
486 | case 1: \ |
487 | unsafe_put_user(__s->sig[0] >> 32, &__c->sig[1], label); \ |
488 | unsafe_put_user(__s->sig[0], &__c->sig[0], label); \ |
489 | } \ |
490 | } while (0) |
491 | |
492 | #define unsafe_get_compat_sigset(set, compat, label) do { \ |
493 | const compat_sigset_t __user *__c = compat; \ |
494 | compat_sigset_word hi, lo; \ |
495 | sigset_t *__s = set; \ |
496 | \ |
497 | switch (_NSIG_WORDS) { \ |
498 | case 4: \ |
499 | unsafe_get_user(lo, &__c->sig[7], label); \ |
500 | unsafe_get_user(hi, &__c->sig[6], label); \ |
501 | __s->sig[3] = hi | (((long)lo) << 32); \ |
502 | fallthrough; \ |
503 | case 3: \ |
504 | unsafe_get_user(lo, &__c->sig[5], label); \ |
505 | unsafe_get_user(hi, &__c->sig[4], label); \ |
506 | __s->sig[2] = hi | (((long)lo) << 32); \ |
507 | fallthrough; \ |
508 | case 2: \ |
509 | unsafe_get_user(lo, &__c->sig[3], label); \ |
510 | unsafe_get_user(hi, &__c->sig[2], label); \ |
511 | __s->sig[1] = hi | (((long)lo) << 32); \ |
512 | fallthrough; \ |
513 | case 1: \ |
514 | unsafe_get_user(lo, &__c->sig[1], label); \ |
515 | unsafe_get_user(hi, &__c->sig[0], label); \ |
516 | __s->sig[0] = hi | (((long)lo) << 32); \ |
517 | } \ |
518 | } while (0) |
519 | #else |
520 | #define unsafe_put_compat_sigset(compat, set, label) do { \ |
521 | compat_sigset_t __user *__c = compat; \ |
522 | const sigset_t *__s = set; \ |
523 | \ |
524 | unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \ |
525 | } while (0) |
526 | |
527 | #define unsafe_get_compat_sigset(set, compat, label) do { \ |
528 | const compat_sigset_t __user *__c = compat; \ |
529 | sigset_t *__s = set; \ |
530 | \ |
531 | unsafe_copy_from_user(__s, __c, sizeof(*__c), label); \ |
532 | } while (0) |
533 | #endif |
534 | |
535 | extern int compat_ptrace_request(struct task_struct *child, |
536 | compat_long_t request, |
537 | compat_ulong_t addr, compat_ulong_t data); |
538 | |
539 | extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
540 | compat_ulong_t addr, compat_ulong_t data); |
541 | |
542 | struct epoll_event; /* fortunately, this one is fixed-layout */ |
543 | |
544 | int compat_restore_altstack(const compat_stack_t __user *uss); |
545 | int __compat_save_altstack(compat_stack_t __user *, unsigned long); |
546 | #define unsafe_compat_save_altstack(uss, sp, label) do { \ |
547 | compat_stack_t __user *__uss = uss; \ |
548 | struct task_struct *t = current; \ |
549 | unsafe_put_user(ptr_to_compat((void __user *)t->sas_ss_sp), \ |
550 | &__uss->ss_sp, label); \ |
551 | unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \ |
552 | unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \ |
553 | } while (0); |
554 | |
555 | /* |
556 | * These syscall function prototypes are kept in the same order as |
557 | * include/uapi/asm-generic/unistd.h. Deprecated or obsolete system calls |
558 | * go below. |
559 | * |
560 | * Please note that these prototypes here are only provided for information |
561 | * purposes, for static analysis, and for linking from the syscall table. |
562 | * These functions should not be called elsewhere from kernel code. |
563 | * |
564 | * As the syscall calling convention may be different from the default |
565 | * for architectures overriding the syscall calling convention, do not |
566 | * include the prototypes if CONFIG_ARCH_HAS_SYSCALL_WRAPPER is enabled. |
567 | */ |
568 | #ifndef CONFIG_ARCH_HAS_SYSCALL_WRAPPER |
569 | asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); |
570 | asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr, |
571 | u32 __user *iocb); |
572 | asmlinkage long compat_sys_io_pgetevents(compat_aio_context_t ctx_id, |
573 | compat_long_t min_nr, |
574 | compat_long_t nr, |
575 | struct io_event __user *events, |
576 | struct old_timespec32 __user *timeout, |
577 | const struct __compat_aio_sigset __user *usig); |
578 | asmlinkage long compat_sys_io_pgetevents_time64(compat_aio_context_t ctx_id, |
579 | compat_long_t min_nr, |
580 | compat_long_t nr, |
581 | struct io_event __user *events, |
582 | struct __kernel_timespec __user *timeout, |
583 | const struct __compat_aio_sigset __user *usig); |
584 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
585 | struct epoll_event __user *events, |
586 | int maxevents, int timeout, |
587 | const compat_sigset_t __user *sigmask, |
588 | compat_size_t sigsetsize); |
589 | asmlinkage long compat_sys_epoll_pwait2(int epfd, |
590 | struct epoll_event __user *events, |
591 | int maxevents, |
592 | const struct __kernel_timespec __user *timeout, |
593 | const compat_sigset_t __user *sigmask, |
594 | compat_size_t sigsetsize); |
595 | asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, |
596 | compat_ulong_t arg); |
597 | asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, |
598 | compat_ulong_t arg); |
599 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, |
600 | compat_ulong_t arg); |
601 | asmlinkage long compat_sys_statfs(const char __user *pathname, |
602 | struct compat_statfs __user *buf); |
603 | asmlinkage long compat_sys_statfs64(const char __user *pathname, |
604 | compat_size_t sz, |
605 | struct compat_statfs64 __user *buf); |
606 | asmlinkage long compat_sys_fstatfs(unsigned int fd, |
607 | struct compat_statfs __user *buf); |
608 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, |
609 | struct compat_statfs64 __user *buf); |
610 | asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); |
611 | asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); |
612 | /* No generic prototype for truncate64, ftruncate64, fallocate */ |
613 | asmlinkage long compat_sys_openat(int dfd, const char __user *filename, |
614 | int flags, umode_t mode); |
615 | asmlinkage long compat_sys_getdents(unsigned int fd, |
616 | struct compat_linux_dirent __user *dirent, |
617 | unsigned int count); |
618 | asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); |
619 | /* No generic prototype for pread64 and pwrite64 */ |
620 | asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, |
621 | const struct iovec __user *vec, |
622 | compat_ulong_t vlen, u32 pos_low, u32 pos_high); |
623 | asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, |
624 | const struct iovec __user *vec, |
625 | compat_ulong_t vlen, u32 pos_low, u32 pos_high); |
626 | #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 |
627 | asmlinkage long compat_sys_preadv64(unsigned long fd, |
628 | const struct iovec __user *vec, |
629 | unsigned long vlen, loff_t pos); |
630 | #endif |
631 | |
632 | #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 |
633 | asmlinkage long compat_sys_pwritev64(unsigned long fd, |
634 | const struct iovec __user *vec, |
635 | unsigned long vlen, loff_t pos); |
636 | #endif |
637 | asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, |
638 | compat_off_t __user *offset, compat_size_t count); |
639 | asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, |
640 | compat_loff_t __user *offset, compat_size_t count); |
641 | asmlinkage long compat_sys_pselect6_time32(int n, compat_ulong_t __user *inp, |
642 | compat_ulong_t __user *outp, |
643 | compat_ulong_t __user *exp, |
644 | struct old_timespec32 __user *tsp, |
645 | void __user *sig); |
646 | asmlinkage long compat_sys_pselect6_time64(int n, compat_ulong_t __user *inp, |
647 | compat_ulong_t __user *outp, |
648 | compat_ulong_t __user *exp, |
649 | struct __kernel_timespec __user *tsp, |
650 | void __user *sig); |
651 | asmlinkage long compat_sys_ppoll_time32(struct pollfd __user *ufds, |
652 | unsigned int nfds, |
653 | struct old_timespec32 __user *tsp, |
654 | const compat_sigset_t __user *sigmask, |
655 | compat_size_t sigsetsize); |
656 | asmlinkage long compat_sys_ppoll_time64(struct pollfd __user *ufds, |
657 | unsigned int nfds, |
658 | struct __kernel_timespec __user *tsp, |
659 | const compat_sigset_t __user *sigmask, |
660 | compat_size_t sigsetsize); |
661 | asmlinkage long compat_sys_signalfd4(int ufd, |
662 | const compat_sigset_t __user *sigmask, |
663 | compat_size_t sigsetsize, int flags); |
664 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, |
665 | const char __user *filename, |
666 | struct compat_stat __user *statbuf, |
667 | int flag); |
668 | asmlinkage long compat_sys_newfstat(unsigned int fd, |
669 | struct compat_stat __user *statbuf); |
670 | /* No generic prototype for sync_file_range and sync_file_range2 */ |
671 | asmlinkage long compat_sys_waitid(int, compat_pid_t, |
672 | struct compat_siginfo __user *, int, |
673 | struct compat_rusage __user *); |
674 | asmlinkage long |
675 | compat_sys_set_robust_list(struct compat_robust_list_head __user *head, |
676 | compat_size_t len); |
677 | asmlinkage long |
678 | compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, |
679 | compat_size_t __user *len_ptr); |
680 | asmlinkage long compat_sys_getitimer(int which, |
681 | struct old_itimerval32 __user *it); |
682 | asmlinkage long compat_sys_setitimer(int which, |
683 | struct old_itimerval32 __user *in, |
684 | struct old_itimerval32 __user *out); |
685 | asmlinkage long compat_sys_kexec_load(compat_ulong_t entry, |
686 | compat_ulong_t nr_segments, |
687 | struct compat_kexec_segment __user *, |
688 | compat_ulong_t flags); |
689 | asmlinkage long compat_sys_timer_create(clockid_t which_clock, |
690 | struct compat_sigevent __user *timer_event_spec, |
691 | timer_t __user *created_timer_id); |
692 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
693 | compat_long_t addr, compat_long_t data); |
694 | asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, |
695 | unsigned int len, |
696 | compat_ulong_t __user *user_mask_ptr); |
697 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, |
698 | unsigned int len, |
699 | compat_ulong_t __user *user_mask_ptr); |
700 | asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, |
701 | compat_stack_t __user *uoss_ptr); |
702 | asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, |
703 | compat_size_t sigsetsize); |
704 | #ifndef CONFIG_ODD_RT_SIGACTION |
705 | asmlinkage long compat_sys_rt_sigaction(int, |
706 | const struct compat_sigaction __user *, |
707 | struct compat_sigaction __user *, |
708 | compat_size_t); |
709 | #endif |
710 | asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, |
711 | compat_sigset_t __user *oset, |
712 | compat_size_t sigsetsize); |
713 | asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset, |
714 | compat_size_t sigsetsize); |
715 | asmlinkage long compat_sys_rt_sigtimedwait_time32(compat_sigset_t __user *uthese, |
716 | struct compat_siginfo __user *uinfo, |
717 | struct old_timespec32 __user *uts, compat_size_t sigsetsize); |
718 | asmlinkage long compat_sys_rt_sigtimedwait_time64(compat_sigset_t __user *uthese, |
719 | struct compat_siginfo __user *uinfo, |
720 | struct __kernel_timespec __user *uts, compat_size_t sigsetsize); |
721 | asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig, |
722 | struct compat_siginfo __user *uinfo); |
723 | /* No generic prototype for rt_sigreturn */ |
724 | asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); |
725 | asmlinkage long compat_sys_getrlimit(unsigned int resource, |
726 | struct compat_rlimit __user *rlim); |
727 | asmlinkage long compat_sys_setrlimit(unsigned int resource, |
728 | struct compat_rlimit __user *rlim); |
729 | asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); |
730 | asmlinkage long compat_sys_gettimeofday(struct old_timeval32 __user *tv, |
731 | struct timezone __user *tz); |
732 | asmlinkage long compat_sys_settimeofday(struct old_timeval32 __user *tv, |
733 | struct timezone __user *tz); |
734 | asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); |
735 | asmlinkage long compat_sys_mq_open(const char __user *u_name, |
736 | int oflag, compat_mode_t mode, |
737 | struct compat_mq_attr __user *u_attr); |
738 | asmlinkage long compat_sys_mq_notify(mqd_t mqdes, |
739 | const struct compat_sigevent __user *u_notification); |
740 | asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, |
741 | const struct compat_mq_attr __user *u_mqstat, |
742 | struct compat_mq_attr __user *u_omqstat); |
743 | asmlinkage long compat_sys_msgctl(int first, int second, void __user *uptr); |
744 | asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, |
745 | compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); |
746 | asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, |
747 | compat_ssize_t msgsz, int msgflg); |
748 | asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg); |
749 | asmlinkage long compat_sys_shmctl(int first, int second, void __user *uptr); |
750 | asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); |
751 | asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len, |
752 | unsigned flags, struct sockaddr __user *addr, |
753 | int __user *addrlen); |
754 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, |
755 | unsigned flags); |
756 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, |
757 | unsigned int flags); |
758 | /* No generic prototype for readahead */ |
759 | asmlinkage long compat_sys_keyctl(u32 option, |
760 | u32 arg2, u32 arg3, u32 arg4, u32 arg5); |
761 | asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, |
762 | const compat_uptr_t __user *envp); |
763 | /* No generic prototype for fadvise64_64 */ |
764 | /* CONFIG_MMU only */ |
765 | asmlinkage long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, |
766 | compat_pid_t pid, int sig, |
767 | struct compat_siginfo __user *uinfo); |
768 | asmlinkage long compat_sys_recvmmsg_time64(int fd, struct compat_mmsghdr __user *mmsg, |
769 | unsigned vlen, unsigned int flags, |
770 | struct __kernel_timespec __user *timeout); |
771 | asmlinkage long compat_sys_recvmmsg_time32(int fd, struct compat_mmsghdr __user *mmsg, |
772 | unsigned vlen, unsigned int flags, |
773 | struct old_timespec32 __user *timeout); |
774 | asmlinkage long compat_sys_wait4(compat_pid_t pid, |
775 | compat_uint_t __user *stat_addr, int options, |
776 | struct compat_rusage __user *ru); |
777 | asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, |
778 | int, const char __user *); |
779 | asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, |
780 | struct file_handle __user *handle, |
781 | int flags); |
782 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
783 | unsigned vlen, unsigned int flags); |
784 | asmlinkage long compat_sys_execveat(int dfd, const char __user *filename, |
785 | const compat_uptr_t __user *argv, |
786 | const compat_uptr_t __user *envp, int flags); |
787 | asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd, |
788 | const struct iovec __user *vec, |
789 | compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); |
790 | asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, |
791 | const struct iovec __user *vec, |
792 | compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags); |
793 | #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 |
794 | asmlinkage long compat_sys_preadv64v2(unsigned long fd, |
795 | const struct iovec __user *vec, |
796 | unsigned long vlen, loff_t pos, rwf_t flags); |
797 | #endif |
798 | |
799 | #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 |
800 | asmlinkage long compat_sys_pwritev64v2(unsigned long fd, |
801 | const struct iovec __user *vec, |
802 | unsigned long vlen, loff_t pos, rwf_t flags); |
803 | #endif |
804 | |
805 | |
806 | /* |
807 | * Deprecated system calls which are still defined in |
808 | * include/uapi/asm-generic/unistd.h and wanted by >= 1 arch |
809 | */ |
810 | |
811 | /* __ARCH_WANT_SYSCALL_NO_AT */ |
812 | asmlinkage long compat_sys_open(const char __user *filename, int flags, |
813 | umode_t mode); |
814 | |
815 | /* __ARCH_WANT_SYSCALL_NO_FLAGS */ |
816 | asmlinkage long compat_sys_signalfd(int ufd, |
817 | const compat_sigset_t __user *sigmask, |
818 | compat_size_t sigsetsize); |
819 | |
820 | /* __ARCH_WANT_SYSCALL_OFF_T */ |
821 | asmlinkage long compat_sys_newstat(const char __user *filename, |
822 | struct compat_stat __user *statbuf); |
823 | asmlinkage long compat_sys_newlstat(const char __user *filename, |
824 | struct compat_stat __user *statbuf); |
825 | |
826 | /* __ARCH_WANT_SYSCALL_DEPRECATED */ |
827 | asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, |
828 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, |
829 | struct old_timeval32 __user *tvp); |
830 | asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); |
831 | asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len, |
832 | unsigned flags); |
833 | |
834 | /* obsolete */ |
835 | asmlinkage long compat_sys_old_readdir(unsigned int fd, |
836 | struct compat_old_linux_dirent __user *, |
837 | unsigned int count); |
838 | |
839 | /* obsolete */ |
840 | asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); |
841 | |
842 | /* obsolete */ |
843 | asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32); |
844 | |
845 | /* obsolete */ |
846 | #ifdef __ARCH_WANT_SYS_SIGPENDING |
847 | asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set); |
848 | #endif |
849 | |
850 | #ifdef __ARCH_WANT_SYS_SIGPROCMASK |
851 | asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *nset, |
852 | compat_old_sigset_t __user *oset); |
853 | #endif |
854 | #ifdef CONFIG_COMPAT_OLD_SIGACTION |
855 | asmlinkage long compat_sys_sigaction(int sig, |
856 | const struct compat_old_sigaction __user *act, |
857 | struct compat_old_sigaction __user *oact); |
858 | #endif |
859 | |
860 | /* obsolete */ |
861 | asmlinkage long compat_sys_socketcall(int call, u32 __user *args); |
862 | |
863 | #ifdef __ARCH_WANT_COMPAT_TRUNCATE64 |
864 | asmlinkage long compat_sys_truncate64(const char __user *pathname, compat_arg_u64(len)); |
865 | #endif |
866 | |
867 | #ifdef __ARCH_WANT_COMPAT_FTRUNCATE64 |
868 | asmlinkage long compat_sys_ftruncate64(unsigned int fd, compat_arg_u64(len)); |
869 | #endif |
870 | |
871 | #ifdef __ARCH_WANT_COMPAT_FALLOCATE |
872 | asmlinkage long compat_sys_fallocate(int fd, int mode, compat_arg_u64(offset), |
873 | compat_arg_u64(len)); |
874 | #endif |
875 | |
876 | #ifdef __ARCH_WANT_COMPAT_PREAD64 |
877 | asmlinkage long compat_sys_pread64(unsigned int fd, char __user *buf, size_t count, |
878 | compat_arg_u64(pos)); |
879 | #endif |
880 | |
881 | #ifdef __ARCH_WANT_COMPAT_PWRITE64 |
882 | asmlinkage long compat_sys_pwrite64(unsigned int fd, const char __user *buf, size_t count, |
883 | compat_arg_u64(pos)); |
884 | #endif |
885 | |
886 | #ifdef __ARCH_WANT_COMPAT_SYNC_FILE_RANGE |
887 | asmlinkage long compat_sys_sync_file_range(int fd, compat_arg_u64(pos), |
888 | compat_arg_u64(nbytes), unsigned int flags); |
889 | #endif |
890 | |
891 | #ifdef __ARCH_WANT_COMPAT_FADVISE64_64 |
892 | asmlinkage long compat_sys_fadvise64_64(int fd, compat_arg_u64(pos), |
893 | compat_arg_u64(len), int advice); |
894 | #endif |
895 | |
896 | #ifdef __ARCH_WANT_COMPAT_READAHEAD |
897 | asmlinkage long compat_sys_readahead(int fd, compat_arg_u64(offset), size_t count); |
898 | #endif |
899 | |
900 | #endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */ |
901 | |
902 | /** |
903 | * ns_to_old_timeval32 - Compat version of ns_to_timeval |
904 | * @nsec: the nanoseconds value to be converted |
905 | * |
906 | * Returns the old_timeval32 representation of the nsec parameter. |
907 | */ |
908 | static inline struct old_timeval32 ns_to_old_timeval32(s64 nsec) |
909 | { |
910 | struct __kernel_old_timeval tv; |
911 | struct old_timeval32 ctv; |
912 | |
913 | tv = ns_to_kernel_old_timeval(nsec); |
914 | ctv.tv_sec = tv.tv_sec; |
915 | ctv.tv_usec = tv.tv_usec; |
916 | |
917 | return ctv; |
918 | } |
919 | |
920 | /* |
921 | * Kernel code should not call compat syscalls (i.e., compat_sys_xyzyyz()) |
922 | * directly. Instead, use one of the functions which work equivalently, such |
923 | * as the kcompat_sys_xyzyyz() functions prototyped below. |
924 | */ |
925 | |
926 | int kcompat_sys_statfs64(const char __user * pathname, compat_size_t sz, |
927 | struct compat_statfs64 __user * buf); |
928 | int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz, |
929 | struct compat_statfs64 __user * buf); |
930 | |
931 | #ifdef CONFIG_COMPAT |
932 | |
933 | /* |
934 | * For most but not all architectures, "am I in a compat syscall?" and |
935 | * "am I a compat task?" are the same question. For architectures on which |
936 | * they aren't the same question, arch code can override in_compat_syscall. |
937 | */ |
938 | #ifndef in_compat_syscall |
939 | static inline bool in_compat_syscall(void) { return is_compat_task(); } |
940 | #endif |
941 | |
942 | #else /* !CONFIG_COMPAT */ |
943 | |
944 | #define is_compat_task() (0) |
945 | /* Ensure no one redefines in_compat_syscall() under !CONFIG_COMPAT */ |
946 | #define in_compat_syscall in_compat_syscall |
947 | static inline bool in_compat_syscall(void) { return false; } |
948 | |
949 | #endif /* CONFIG_COMPAT */ |
950 | |
951 | #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t)) |
952 | |
953 | #define BITS_TO_COMPAT_LONGS(bits) DIV_ROUND_UP(bits, BITS_PER_COMPAT_LONG) |
954 | |
955 | long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, |
956 | unsigned long bitmap_size); |
957 | long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, |
958 | unsigned long bitmap_size); |
959 | |
960 | /* |
961 | * Some legacy ABIs like the i386 one use less than natural alignment for 64-bit |
962 | * types, and will need special compat treatment for that. Most architectures |
963 | * don't need that special handling even for compat syscalls. |
964 | */ |
965 | #ifndef compat_need_64bit_alignment_fixup |
966 | #define compat_need_64bit_alignment_fixup() false |
967 | #endif |
968 | |
969 | /* |
970 | * A pointer passed in from user mode. This should not |
971 | * be used for syscall parameters, just declare them |
972 | * as pointers because the syscall entry code will have |
973 | * appropriately converted them already. |
974 | */ |
975 | #ifndef compat_ptr |
976 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
977 | { |
978 | return (void __user *)(unsigned long)uptr; |
979 | } |
980 | #endif |
981 | |
982 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) |
983 | { |
984 | return (u32)(unsigned long)uptr; |
985 | } |
986 | |
987 | #endif /* _LINUX_COMPAT_H */ |
988 | |