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