Commit 3a49a0f7181c243aa04e6c5e44ca70a90ead8f9a

Authored by Heiko Carstens
1 parent 8eee9093cd

net/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types

In order to allow the COMPAT_SYSCALL_DEFINE macro generate code that
performs proper zero and sign extension convert all 64 bit parameters
to their corresponding 32 bit compat counterparts.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

Showing 2 changed files with 6 additions and 6 deletions Inline Diff

include/linux/compat.h
1 #ifndef _LINUX_COMPAT_H 1 #ifndef _LINUX_COMPAT_H
2 #define _LINUX_COMPAT_H 2 #define _LINUX_COMPAT_H
3 /* 3 /*
4 * These are the type definitions for the architecture specific 4 * These are the type definitions for the architecture specific
5 * syscall compatibility layer. 5 * syscall compatibility layer.
6 */ 6 */
7 7
8 #ifdef CONFIG_COMPAT 8 #ifdef CONFIG_COMPAT
9 9
10 #include <linux/stat.h> 10 #include <linux/stat.h>
11 #include <linux/param.h> /* for HZ */ 11 #include <linux/param.h> /* for HZ */
12 #include <linux/sem.h> 12 #include <linux/sem.h>
13 #include <linux/socket.h> 13 #include <linux/socket.h>
14 #include <linux/if.h> 14 #include <linux/if.h>
15 #include <linux/fs.h> 15 #include <linux/fs.h>
16 #include <linux/aio_abi.h> /* for aio_context_t */ 16 #include <linux/aio_abi.h> /* for aio_context_t */
17 17
18 #include <asm/compat.h> 18 #include <asm/compat.h>
19 #include <asm/siginfo.h> 19 #include <asm/siginfo.h>
20 #include <asm/signal.h> 20 #include <asm/signal.h>
21 21
22 #ifndef COMPAT_USE_64BIT_TIME 22 #ifndef COMPAT_USE_64BIT_TIME
23 #define COMPAT_USE_64BIT_TIME 0 23 #define COMPAT_USE_64BIT_TIME 0
24 #endif 24 #endif
25 25
26 #ifndef __SC_DELOUSE 26 #ifndef __SC_DELOUSE
27 #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v)) 27 #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
28 #endif 28 #endif
29 29
30 #define COMPAT_SYSCALL_DEFINE0(name) \ 30 #define COMPAT_SYSCALL_DEFINE0(name) \
31 asmlinkage long compat_sys_##name(void) 31 asmlinkage long compat_sys_##name(void)
32 32
33 #define COMPAT_SYSCALL_DEFINE1(name, ...) \ 33 #define COMPAT_SYSCALL_DEFINE1(name, ...) \
34 COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) 34 COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
35 #define COMPAT_SYSCALL_DEFINE2(name, ...) \ 35 #define COMPAT_SYSCALL_DEFINE2(name, ...) \
36 COMPAT_SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) 36 COMPAT_SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
37 #define COMPAT_SYSCALL_DEFINE3(name, ...) \ 37 #define COMPAT_SYSCALL_DEFINE3(name, ...) \
38 COMPAT_SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) 38 COMPAT_SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
39 #define COMPAT_SYSCALL_DEFINE4(name, ...) \ 39 #define COMPAT_SYSCALL_DEFINE4(name, ...) \
40 COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) 40 COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
41 #define COMPAT_SYSCALL_DEFINE5(name, ...) \ 41 #define COMPAT_SYSCALL_DEFINE5(name, ...) \
42 COMPAT_SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) 42 COMPAT_SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
43 #define COMPAT_SYSCALL_DEFINE6(name, ...) \ 43 #define COMPAT_SYSCALL_DEFINE6(name, ...) \
44 COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) 44 COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
45 45
46 #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ 46 #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
47 asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ 47 asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\
48 __attribute__((alias(__stringify(compat_SyS##name)))); \ 48 __attribute__((alias(__stringify(compat_SyS##name)))); \
49 static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ 49 static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
50 asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));\ 50 asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));\
51 asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ 51 asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\
52 { \ 52 { \
53 return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ 53 return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
54 } \ 54 } \
55 static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) 55 static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
56 56
57 #ifndef compat_user_stack_pointer 57 #ifndef compat_user_stack_pointer
58 #define compat_user_stack_pointer() current_user_stack_pointer() 58 #define compat_user_stack_pointer() current_user_stack_pointer()
59 #endif 59 #endif
60 #ifndef compat_sigaltstack /* we'll need that for MIPS */ 60 #ifndef compat_sigaltstack /* we'll need that for MIPS */
61 typedef struct compat_sigaltstack { 61 typedef struct compat_sigaltstack {
62 compat_uptr_t ss_sp; 62 compat_uptr_t ss_sp;
63 int ss_flags; 63 int ss_flags;
64 compat_size_t ss_size; 64 compat_size_t ss_size;
65 } compat_stack_t; 65 } compat_stack_t;
66 #endif 66 #endif
67 67
68 #define compat_jiffies_to_clock_t(x) \ 68 #define compat_jiffies_to_clock_t(x) \
69 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) 69 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
70 70
71 typedef __compat_uid32_t compat_uid_t; 71 typedef __compat_uid32_t compat_uid_t;
72 typedef __compat_gid32_t compat_gid_t; 72 typedef __compat_gid32_t compat_gid_t;
73 73
74 typedef compat_ulong_t compat_aio_context_t; 74 typedef compat_ulong_t compat_aio_context_t;
75 75
76 struct compat_sel_arg_struct; 76 struct compat_sel_arg_struct;
77 struct rusage; 77 struct rusage;
78 78
79 struct compat_itimerspec { 79 struct compat_itimerspec {
80 struct compat_timespec it_interval; 80 struct compat_timespec it_interval;
81 struct compat_timespec it_value; 81 struct compat_timespec it_value;
82 }; 82 };
83 83
84 struct compat_utimbuf { 84 struct compat_utimbuf {
85 compat_time_t actime; 85 compat_time_t actime;
86 compat_time_t modtime; 86 compat_time_t modtime;
87 }; 87 };
88 88
89 struct compat_itimerval { 89 struct compat_itimerval {
90 struct compat_timeval it_interval; 90 struct compat_timeval it_interval;
91 struct compat_timeval it_value; 91 struct compat_timeval it_value;
92 }; 92 };
93 93
94 struct compat_tms { 94 struct compat_tms {
95 compat_clock_t tms_utime; 95 compat_clock_t tms_utime;
96 compat_clock_t tms_stime; 96 compat_clock_t tms_stime;
97 compat_clock_t tms_cutime; 97 compat_clock_t tms_cutime;
98 compat_clock_t tms_cstime; 98 compat_clock_t tms_cstime;
99 }; 99 };
100 100
101 struct compat_timex { 101 struct compat_timex {
102 compat_uint_t modes; 102 compat_uint_t modes;
103 compat_long_t offset; 103 compat_long_t offset;
104 compat_long_t freq; 104 compat_long_t freq;
105 compat_long_t maxerror; 105 compat_long_t maxerror;
106 compat_long_t esterror; 106 compat_long_t esterror;
107 compat_int_t status; 107 compat_int_t status;
108 compat_long_t constant; 108 compat_long_t constant;
109 compat_long_t precision; 109 compat_long_t precision;
110 compat_long_t tolerance; 110 compat_long_t tolerance;
111 struct compat_timeval time; 111 struct compat_timeval time;
112 compat_long_t tick; 112 compat_long_t tick;
113 compat_long_t ppsfreq; 113 compat_long_t ppsfreq;
114 compat_long_t jitter; 114 compat_long_t jitter;
115 compat_int_t shift; 115 compat_int_t shift;
116 compat_long_t stabil; 116 compat_long_t stabil;
117 compat_long_t jitcnt; 117 compat_long_t jitcnt;
118 compat_long_t calcnt; 118 compat_long_t calcnt;
119 compat_long_t errcnt; 119 compat_long_t errcnt;
120 compat_long_t stbcnt; 120 compat_long_t stbcnt;
121 compat_int_t tai; 121 compat_int_t tai;
122 122
123 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; 123 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
124 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32; 124 compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
125 compat_int_t:32; compat_int_t:32; compat_int_t:32; 125 compat_int_t:32; compat_int_t:32; compat_int_t:32;
126 }; 126 };
127 127
128 #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) 128 #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
129 129
130 typedef struct { 130 typedef struct {
131 compat_sigset_word sig[_COMPAT_NSIG_WORDS]; 131 compat_sigset_word sig[_COMPAT_NSIG_WORDS];
132 } compat_sigset_t; 132 } compat_sigset_t;
133 133
134 struct compat_sigaction { 134 struct compat_sigaction {
135 #ifndef __ARCH_HAS_IRIX_SIGACTION 135 #ifndef __ARCH_HAS_IRIX_SIGACTION
136 compat_uptr_t sa_handler; 136 compat_uptr_t sa_handler;
137 compat_ulong_t sa_flags; 137 compat_ulong_t sa_flags;
138 #else 138 #else
139 compat_uint_t sa_flags; 139 compat_uint_t sa_flags;
140 compat_uptr_t sa_handler; 140 compat_uptr_t sa_handler;
141 #endif 141 #endif
142 #ifdef __ARCH_HAS_SA_RESTORER 142 #ifdef __ARCH_HAS_SA_RESTORER
143 compat_uptr_t sa_restorer; 143 compat_uptr_t sa_restorer;
144 #endif 144 #endif
145 compat_sigset_t sa_mask __packed; 145 compat_sigset_t sa_mask __packed;
146 }; 146 };
147 147
148 /* 148 /*
149 * These functions operate strictly on struct compat_time* 149 * These functions operate strictly on struct compat_time*
150 */ 150 */
151 extern int get_compat_timespec(struct timespec *, 151 extern int get_compat_timespec(struct timespec *,
152 const struct compat_timespec __user *); 152 const struct compat_timespec __user *);
153 extern int put_compat_timespec(const struct timespec *, 153 extern int put_compat_timespec(const struct timespec *,
154 struct compat_timespec __user *); 154 struct compat_timespec __user *);
155 extern int get_compat_timeval(struct timeval *, 155 extern int get_compat_timeval(struct timeval *,
156 const struct compat_timeval __user *); 156 const struct compat_timeval __user *);
157 extern int put_compat_timeval(const struct timeval *, 157 extern int put_compat_timeval(const struct timeval *,
158 struct compat_timeval __user *); 158 struct compat_timeval __user *);
159 /* 159 /*
160 * These functions operate on 32- or 64-bit specs depending on 160 * These functions operate on 32- or 64-bit specs depending on
161 * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the 161 * COMPAT_USE_64BIT_TIME, hence the void user pointer arguments and the
162 * naming as compat_get/put_ rather than get/put_compat_. 162 * naming as compat_get/put_ rather than get/put_compat_.
163 */ 163 */
164 extern int compat_get_timespec(struct timespec *, const void __user *); 164 extern int compat_get_timespec(struct timespec *, const void __user *);
165 extern int compat_put_timespec(const struct timespec *, void __user *); 165 extern int compat_put_timespec(const struct timespec *, void __user *);
166 extern int compat_get_timeval(struct timeval *, const void __user *); 166 extern int compat_get_timeval(struct timeval *, const void __user *);
167 extern int compat_put_timeval(const struct timeval *, void __user *); 167 extern int compat_put_timeval(const struct timeval *, void __user *);
168 168
169 struct compat_iovec { 169 struct compat_iovec {
170 compat_uptr_t iov_base; 170 compat_uptr_t iov_base;
171 compat_size_t iov_len; 171 compat_size_t iov_len;
172 }; 172 };
173 173
174 struct compat_rlimit { 174 struct compat_rlimit {
175 compat_ulong_t rlim_cur; 175 compat_ulong_t rlim_cur;
176 compat_ulong_t rlim_max; 176 compat_ulong_t rlim_max;
177 }; 177 };
178 178
179 struct compat_rusage { 179 struct compat_rusage {
180 struct compat_timeval ru_utime; 180 struct compat_timeval ru_utime;
181 struct compat_timeval ru_stime; 181 struct compat_timeval ru_stime;
182 compat_long_t ru_maxrss; 182 compat_long_t ru_maxrss;
183 compat_long_t ru_ixrss; 183 compat_long_t ru_ixrss;
184 compat_long_t ru_idrss; 184 compat_long_t ru_idrss;
185 compat_long_t ru_isrss; 185 compat_long_t ru_isrss;
186 compat_long_t ru_minflt; 186 compat_long_t ru_minflt;
187 compat_long_t ru_majflt; 187 compat_long_t ru_majflt;
188 compat_long_t ru_nswap; 188 compat_long_t ru_nswap;
189 compat_long_t ru_inblock; 189 compat_long_t ru_inblock;
190 compat_long_t ru_oublock; 190 compat_long_t ru_oublock;
191 compat_long_t ru_msgsnd; 191 compat_long_t ru_msgsnd;
192 compat_long_t ru_msgrcv; 192 compat_long_t ru_msgrcv;
193 compat_long_t ru_nsignals; 193 compat_long_t ru_nsignals;
194 compat_long_t ru_nvcsw; 194 compat_long_t ru_nvcsw;
195 compat_long_t ru_nivcsw; 195 compat_long_t ru_nivcsw;
196 }; 196 };
197 197
198 extern int put_compat_rusage(const struct rusage *, 198 extern int put_compat_rusage(const struct rusage *,
199 struct compat_rusage __user *); 199 struct compat_rusage __user *);
200 200
201 struct compat_siginfo; 201 struct compat_siginfo;
202 202
203 extern asmlinkage long compat_sys_waitid(int, compat_pid_t, 203 extern asmlinkage long compat_sys_waitid(int, compat_pid_t,
204 struct compat_siginfo __user *, int, 204 struct compat_siginfo __user *, int,
205 struct compat_rusage __user *); 205 struct compat_rusage __user *);
206 206
207 struct compat_dirent { 207 struct compat_dirent {
208 u32 d_ino; 208 u32 d_ino;
209 compat_off_t d_off; 209 compat_off_t d_off;
210 u16 d_reclen; 210 u16 d_reclen;
211 char d_name[256]; 211 char d_name[256];
212 }; 212 };
213 213
214 struct compat_ustat { 214 struct compat_ustat {
215 compat_daddr_t f_tfree; 215 compat_daddr_t f_tfree;
216 compat_ino_t f_tinode; 216 compat_ino_t f_tinode;
217 char f_fname[6]; 217 char f_fname[6];
218 char f_fpack[6]; 218 char f_fpack[6];
219 }; 219 };
220 220
221 #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) 221 #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
222 222
223 typedef struct compat_sigevent { 223 typedef struct compat_sigevent {
224 compat_sigval_t sigev_value; 224 compat_sigval_t sigev_value;
225 compat_int_t sigev_signo; 225 compat_int_t sigev_signo;
226 compat_int_t sigev_notify; 226 compat_int_t sigev_notify;
227 union { 227 union {
228 compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; 228 compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE];
229 compat_int_t _tid; 229 compat_int_t _tid;
230 230
231 struct { 231 struct {
232 compat_uptr_t _function; 232 compat_uptr_t _function;
233 compat_uptr_t _attribute; 233 compat_uptr_t _attribute;
234 } _sigev_thread; 234 } _sigev_thread;
235 } _sigev_un; 235 } _sigev_un;
236 } compat_sigevent_t; 236 } compat_sigevent_t;
237 237
238 struct compat_ifmap { 238 struct compat_ifmap {
239 compat_ulong_t mem_start; 239 compat_ulong_t mem_start;
240 compat_ulong_t mem_end; 240 compat_ulong_t mem_end;
241 unsigned short base_addr; 241 unsigned short base_addr;
242 unsigned char irq; 242 unsigned char irq;
243 unsigned char dma; 243 unsigned char dma;
244 unsigned char port; 244 unsigned char port;
245 }; 245 };
246 246
247 struct compat_if_settings { 247 struct compat_if_settings {
248 unsigned int type; /* Type of physical device or protocol */ 248 unsigned int type; /* Type of physical device or protocol */
249 unsigned int size; /* Size of the data allocated by the caller */ 249 unsigned int size; /* Size of the data allocated by the caller */
250 compat_uptr_t ifs_ifsu; /* union of pointers */ 250 compat_uptr_t ifs_ifsu; /* union of pointers */
251 }; 251 };
252 252
253 struct compat_ifreq { 253 struct compat_ifreq {
254 union { 254 union {
255 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ 255 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
256 } ifr_ifrn; 256 } ifr_ifrn;
257 union { 257 union {
258 struct sockaddr ifru_addr; 258 struct sockaddr ifru_addr;
259 struct sockaddr ifru_dstaddr; 259 struct sockaddr ifru_dstaddr;
260 struct sockaddr ifru_broadaddr; 260 struct sockaddr ifru_broadaddr;
261 struct sockaddr ifru_netmask; 261 struct sockaddr ifru_netmask;
262 struct sockaddr ifru_hwaddr; 262 struct sockaddr ifru_hwaddr;
263 short ifru_flags; 263 short ifru_flags;
264 compat_int_t ifru_ivalue; 264 compat_int_t ifru_ivalue;
265 compat_int_t ifru_mtu; 265 compat_int_t ifru_mtu;
266 struct compat_ifmap ifru_map; 266 struct compat_ifmap ifru_map;
267 char ifru_slave[IFNAMSIZ]; /* Just fits the size */ 267 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
268 char ifru_newname[IFNAMSIZ]; 268 char ifru_newname[IFNAMSIZ];
269 compat_caddr_t ifru_data; 269 compat_caddr_t ifru_data;
270 struct compat_if_settings ifru_settings; 270 struct compat_if_settings ifru_settings;
271 } ifr_ifru; 271 } ifr_ifru;
272 }; 272 };
273 273
274 struct compat_ifconf { 274 struct compat_ifconf {
275 compat_int_t ifc_len; /* size of buffer */ 275 compat_int_t ifc_len; /* size of buffer */
276 compat_caddr_t ifcbuf; 276 compat_caddr_t ifcbuf;
277 }; 277 };
278 278
279 struct compat_robust_list { 279 struct compat_robust_list {
280 compat_uptr_t next; 280 compat_uptr_t next;
281 }; 281 };
282 282
283 struct compat_robust_list_head { 283 struct compat_robust_list_head {
284 struct compat_robust_list list; 284 struct compat_robust_list list;
285 compat_long_t futex_offset; 285 compat_long_t futex_offset;
286 compat_uptr_t list_op_pending; 286 compat_uptr_t list_op_pending;
287 }; 287 };
288 288
289 #ifdef CONFIG_COMPAT_OLD_SIGACTION 289 #ifdef CONFIG_COMPAT_OLD_SIGACTION
290 struct compat_old_sigaction { 290 struct compat_old_sigaction {
291 compat_uptr_t sa_handler; 291 compat_uptr_t sa_handler;
292 compat_old_sigset_t sa_mask; 292 compat_old_sigset_t sa_mask;
293 compat_ulong_t sa_flags; 293 compat_ulong_t sa_flags;
294 compat_uptr_t sa_restorer; 294 compat_uptr_t sa_restorer;
295 }; 295 };
296 #endif 296 #endif
297 297
298 struct compat_statfs; 298 struct compat_statfs;
299 struct compat_statfs64; 299 struct compat_statfs64;
300 struct compat_old_linux_dirent; 300 struct compat_old_linux_dirent;
301 struct compat_linux_dirent; 301 struct compat_linux_dirent;
302 struct linux_dirent64; 302 struct linux_dirent64;
303 struct compat_msghdr; 303 struct compat_msghdr;
304 struct compat_mmsghdr; 304 struct compat_mmsghdr;
305 struct compat_sysinfo; 305 struct compat_sysinfo;
306 struct compat_sysctl_args; 306 struct compat_sysctl_args;
307 struct compat_kexec_segment; 307 struct compat_kexec_segment;
308 struct compat_mq_attr; 308 struct compat_mq_attr;
309 struct compat_msgbuf; 309 struct compat_msgbuf;
310 310
311 extern void compat_exit_robust_list(struct task_struct *curr); 311 extern void compat_exit_robust_list(struct task_struct *curr);
312 312
313 asmlinkage long 313 asmlinkage long
314 compat_sys_set_robust_list(struct compat_robust_list_head __user *head, 314 compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
315 compat_size_t len); 315 compat_size_t len);
316 asmlinkage long 316 asmlinkage long
317 compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, 317 compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
318 compat_size_t __user *len_ptr); 318 compat_size_t __user *len_ptr);
319 319
320 asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32); 320 asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32);
321 asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); 321 asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg);
322 asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg); 322 asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
323 asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, 323 asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
324 compat_ssize_t msgsz, int msgflg); 324 compat_ssize_t msgsz, int msgflg);
325 asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, 325 asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
326 compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg); 326 compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
327 long compat_sys_msgctl(int first, int second, void __user *uptr); 327 long compat_sys_msgctl(int first, int second, void __user *uptr);
328 long compat_sys_shmctl(int first, int second, void __user *uptr); 328 long compat_sys_shmctl(int first, int second, void __user *uptr);
329 long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, 329 long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
330 unsigned nsems, const struct compat_timespec __user *timeout); 330 unsigned nsems, const struct compat_timespec __user *timeout);
331 asmlinkage long compat_sys_keyctl(u32 option, 331 asmlinkage long compat_sys_keyctl(u32 option,
332 u32 arg2, u32 arg3, u32 arg4, u32 arg5); 332 u32 arg2, u32 arg3, u32 arg4, u32 arg5);
333 asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); 333 asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32);
334 334
335 asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd, 335 asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd,
336 const struct compat_iovec __user *vec, compat_ulong_t vlen); 336 const struct compat_iovec __user *vec, compat_ulong_t vlen);
337 asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd, 337 asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd,
338 const struct compat_iovec __user *vec, compat_ulong_t vlen); 338 const struct compat_iovec __user *vec, compat_ulong_t vlen);
339 asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, 339 asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
340 const struct compat_iovec __user *vec, 340 const struct compat_iovec __user *vec,
341 compat_ulong_t vlen, u32 pos_low, u32 pos_high); 341 compat_ulong_t vlen, u32 pos_low, u32 pos_high);
342 asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, 342 asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
343 const struct compat_iovec __user *vec, 343 const struct compat_iovec __user *vec,
344 compat_ulong_t vlen, u32 pos_low, u32 pos_high); 344 compat_ulong_t vlen, u32 pos_low, u32 pos_high);
345 345
346 #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 346 #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
347 asmlinkage long compat_sys_preadv64(unsigned long fd, 347 asmlinkage long compat_sys_preadv64(unsigned long fd,
348 const struct compat_iovec __user *vec, 348 const struct compat_iovec __user *vec,
349 unsigned long vlen, loff_t pos); 349 unsigned long vlen, loff_t pos);
350 #endif 350 #endif
351 351
352 #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 352 #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
353 asmlinkage long compat_sys_pwritev64(unsigned long fd, 353 asmlinkage long compat_sys_pwritev64(unsigned long fd,
354 const struct compat_iovec __user *vec, 354 const struct compat_iovec __user *vec,
355 unsigned long vlen, loff_t pos); 355 unsigned long vlen, loff_t pos);
356 #endif 356 #endif
357 357
358 asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); 358 asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int);
359 359
360 asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, 360 asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
361 const compat_uptr_t __user *envp); 361 const compat_uptr_t __user *envp);
362 362
363 asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, 363 asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
364 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 364 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
365 struct compat_timeval __user *tvp); 365 struct compat_timeval __user *tvp);
366 366
367 asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg); 367 asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg);
368 368
369 asmlinkage long compat_sys_wait4(compat_pid_t pid, 369 asmlinkage long compat_sys_wait4(compat_pid_t pid,
370 compat_uint_t __user *stat_addr, int options, 370 compat_uint_t __user *stat_addr, int options,
371 struct compat_rusage __user *ru); 371 struct compat_rusage __user *ru);
372 372
373 #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t)) 373 #define BITS_PER_COMPAT_LONG (8*sizeof(compat_long_t))
374 374
375 #define BITS_TO_COMPAT_LONGS(bits) \ 375 #define BITS_TO_COMPAT_LONGS(bits) \
376 (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG) 376 (((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG)
377 377
378 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, 378 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
379 unsigned long bitmap_size); 379 unsigned long bitmap_size);
380 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, 380 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
381 unsigned long bitmap_size); 381 unsigned long bitmap_size);
382 int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from); 382 int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from);
383 int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from); 383 int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from);
384 int get_compat_sigevent(struct sigevent *event, 384 int get_compat_sigevent(struct sigevent *event,
385 const struct compat_sigevent __user *u_event); 385 const struct compat_sigevent __user *u_event);
386 long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig, 386 long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
387 struct compat_siginfo __user *uinfo); 387 struct compat_siginfo __user *uinfo);
388 #ifdef CONFIG_COMPAT_OLD_SIGACTION 388 #ifdef CONFIG_COMPAT_OLD_SIGACTION
389 asmlinkage long compat_sys_sigaction(int sig, 389 asmlinkage long compat_sys_sigaction(int sig,
390 const struct compat_old_sigaction __user *act, 390 const struct compat_old_sigaction __user *act,
391 struct compat_old_sigaction __user *oact); 391 struct compat_old_sigaction __user *oact);
392 #endif 392 #endif
393 393
394 static inline int compat_timeval_compare(struct compat_timeval *lhs, 394 static inline int compat_timeval_compare(struct compat_timeval *lhs,
395 struct compat_timeval *rhs) 395 struct compat_timeval *rhs)
396 { 396 {
397 if (lhs->tv_sec < rhs->tv_sec) 397 if (lhs->tv_sec < rhs->tv_sec)
398 return -1; 398 return -1;
399 if (lhs->tv_sec > rhs->tv_sec) 399 if (lhs->tv_sec > rhs->tv_sec)
400 return 1; 400 return 1;
401 return lhs->tv_usec - rhs->tv_usec; 401 return lhs->tv_usec - rhs->tv_usec;
402 } 402 }
403 403
404 static inline int compat_timespec_compare(struct compat_timespec *lhs, 404 static inline int compat_timespec_compare(struct compat_timespec *lhs,
405 struct compat_timespec *rhs) 405 struct compat_timespec *rhs)
406 { 406 {
407 if (lhs->tv_sec < rhs->tv_sec) 407 if (lhs->tv_sec < rhs->tv_sec)
408 return -1; 408 return -1;
409 if (lhs->tv_sec > rhs->tv_sec) 409 if (lhs->tv_sec > rhs->tv_sec)
410 return 1; 410 return 1;
411 return lhs->tv_nsec - rhs->tv_nsec; 411 return lhs->tv_nsec - rhs->tv_nsec;
412 } 412 }
413 413
414 extern int get_compat_itimerspec(struct itimerspec *dst, 414 extern int get_compat_itimerspec(struct itimerspec *dst,
415 const struct compat_itimerspec __user *src); 415 const struct compat_itimerspec __user *src);
416 extern int put_compat_itimerspec(struct compat_itimerspec __user *dst, 416 extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
417 const struct itimerspec *src); 417 const struct itimerspec *src);
418 418
419 asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, 419 asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
420 struct timezone __user *tz); 420 struct timezone __user *tz);
421 asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, 421 asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
422 struct timezone __user *tz); 422 struct timezone __user *tz);
423 423
424 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); 424 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
425 425
426 extern int compat_printk(const char *fmt, ...); 426 extern int compat_printk(const char *fmt, ...);
427 extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); 427 extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
428 extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); 428 extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
429 429
430 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, 430 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
431 compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, 431 compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
432 const compat_ulong_t __user *new_nodes); 432 const compat_ulong_t __user *new_nodes);
433 433
434 extern int compat_ptrace_request(struct task_struct *child, 434 extern int compat_ptrace_request(struct task_struct *child,
435 compat_long_t request, 435 compat_long_t request,
436 compat_ulong_t addr, compat_ulong_t data); 436 compat_ulong_t addr, compat_ulong_t data);
437 437
438 extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 438 extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
439 compat_ulong_t addr, compat_ulong_t data); 439 compat_ulong_t addr, compat_ulong_t data);
440 asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, 440 asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
441 compat_long_t addr, compat_long_t data); 441 compat_long_t addr, compat_long_t data);
442 442
443 asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t); 443 asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, compat_size_t);
444 /* 444 /*
445 * epoll (fs/eventpoll.c) compat bits follow ... 445 * epoll (fs/eventpoll.c) compat bits follow ...
446 */ 446 */
447 struct epoll_event; /* fortunately, this one is fixed-layout */ 447 struct epoll_event; /* fortunately, this one is fixed-layout */
448 asmlinkage long compat_sys_epoll_pwait(int epfd, 448 asmlinkage long compat_sys_epoll_pwait(int epfd,
449 struct epoll_event __user *events, 449 struct epoll_event __user *events,
450 int maxevents, int timeout, 450 int maxevents, int timeout,
451 const compat_sigset_t __user *sigmask, 451 const compat_sigset_t __user *sigmask,
452 compat_size_t sigsetsize); 452 compat_size_t sigsetsize);
453 453
454 asmlinkage long compat_sys_utime(const char __user *filename, 454 asmlinkage long compat_sys_utime(const char __user *filename,
455 struct compat_utimbuf __user *t); 455 struct compat_utimbuf __user *t);
456 asmlinkage long compat_sys_utimensat(unsigned int dfd, 456 asmlinkage long compat_sys_utimensat(unsigned int dfd,
457 const char __user *filename, 457 const char __user *filename,
458 struct compat_timespec __user *t, 458 struct compat_timespec __user *t,
459 int flags); 459 int flags);
460 460
461 asmlinkage long compat_sys_time(compat_time_t __user *tloc); 461 asmlinkage long compat_sys_time(compat_time_t __user *tloc);
462 asmlinkage long compat_sys_stime(compat_time_t __user *tptr); 462 asmlinkage long compat_sys_stime(compat_time_t __user *tptr);
463 asmlinkage long compat_sys_signalfd(int ufd, 463 asmlinkage long compat_sys_signalfd(int ufd,
464 const compat_sigset_t __user *sigmask, 464 const compat_sigset_t __user *sigmask,
465 compat_size_t sigsetsize); 465 compat_size_t sigsetsize);
466 asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, 466 asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
467 const struct compat_itimerspec __user *utmr, 467 const struct compat_itimerspec __user *utmr,
468 struct compat_itimerspec __user *otmr); 468 struct compat_itimerspec __user *otmr);
469 asmlinkage long compat_sys_timerfd_gettime(int ufd, 469 asmlinkage long compat_sys_timerfd_gettime(int ufd,
470 struct compat_itimerspec __user *otmr); 470 struct compat_itimerspec __user *otmr);
471 471
472 asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, 472 asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page,
473 __u32 __user *pages, 473 __u32 __user *pages,
474 const int __user *nodes, 474 const int __user *nodes,
475 int __user *status, 475 int __user *status,
476 int flags); 476 int flags);
477 asmlinkage long compat_sys_futimesat(unsigned int dfd, 477 asmlinkage long compat_sys_futimesat(unsigned int dfd,
478 const char __user *filename, 478 const char __user *filename,
479 struct compat_timeval __user *t); 479 struct compat_timeval __user *t);
480 asmlinkage long compat_sys_utimes(const char __user *filename, 480 asmlinkage long compat_sys_utimes(const char __user *filename,
481 struct compat_timeval __user *t); 481 struct compat_timeval __user *t);
482 asmlinkage long compat_sys_newstat(const char __user *filename, 482 asmlinkage long compat_sys_newstat(const char __user *filename,
483 struct compat_stat __user *statbuf); 483 struct compat_stat __user *statbuf);
484 asmlinkage long compat_sys_newlstat(const char __user *filename, 484 asmlinkage long compat_sys_newlstat(const char __user *filename,
485 struct compat_stat __user *statbuf); 485 struct compat_stat __user *statbuf);
486 asmlinkage long compat_sys_newfstatat(unsigned int dfd, 486 asmlinkage long compat_sys_newfstatat(unsigned int dfd,
487 const char __user *filename, 487 const char __user *filename,
488 struct compat_stat __user *statbuf, 488 struct compat_stat __user *statbuf,
489 int flag); 489 int flag);
490 asmlinkage long compat_sys_newfstat(unsigned int fd, 490 asmlinkage long compat_sys_newfstat(unsigned int fd,
491 struct compat_stat __user *statbuf); 491 struct compat_stat __user *statbuf);
492 asmlinkage long compat_sys_statfs(const char __user *pathname, 492 asmlinkage long compat_sys_statfs(const char __user *pathname,
493 struct compat_statfs __user *buf); 493 struct compat_statfs __user *buf);
494 asmlinkage long compat_sys_fstatfs(unsigned int fd, 494 asmlinkage long compat_sys_fstatfs(unsigned int fd,
495 struct compat_statfs __user *buf); 495 struct compat_statfs __user *buf);
496 asmlinkage long compat_sys_statfs64(const char __user *pathname, 496 asmlinkage long compat_sys_statfs64(const char __user *pathname,
497 compat_size_t sz, 497 compat_size_t sz,
498 struct compat_statfs64 __user *buf); 498 struct compat_statfs64 __user *buf);
499 asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, 499 asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
500 struct compat_statfs64 __user *buf); 500 struct compat_statfs64 __user *buf);
501 asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, 501 asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
502 compat_ulong_t arg); 502 compat_ulong_t arg);
503 asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, 503 asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
504 compat_ulong_t arg); 504 compat_ulong_t arg);
505 asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); 505 asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
506 asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id, 506 asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
507 compat_long_t min_nr, 507 compat_long_t min_nr,
508 compat_long_t nr, 508 compat_long_t nr,
509 struct io_event __user *events, 509 struct io_event __user *events,
510 struct compat_timespec __user *timeout); 510 struct compat_timespec __user *timeout);
511 asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr, 511 asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
512 u32 __user *iocb); 512 u32 __user *iocb);
513 asmlinkage long compat_sys_mount(const char __user *dev_name, 513 asmlinkage long compat_sys_mount(const char __user *dev_name,
514 const char __user *dir_name, 514 const char __user *dir_name,
515 const char __user *type, compat_ulong_t flags, 515 const char __user *type, compat_ulong_t flags,
516 const void __user *data); 516 const void __user *data);
517 asmlinkage long compat_sys_old_readdir(unsigned int fd, 517 asmlinkage long compat_sys_old_readdir(unsigned int fd,
518 struct compat_old_linux_dirent __user *, 518 struct compat_old_linux_dirent __user *,
519 unsigned int count); 519 unsigned int count);
520 asmlinkage long compat_sys_getdents(unsigned int fd, 520 asmlinkage long compat_sys_getdents(unsigned int fd,
521 struct compat_linux_dirent __user *dirent, 521 struct compat_linux_dirent __user *dirent,
522 unsigned int count); 522 unsigned int count);
523 #ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64 523 #ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
524 asmlinkage long compat_sys_getdents64(unsigned int fd, 524 asmlinkage long compat_sys_getdents64(unsigned int fd,
525 struct linux_dirent64 __user *dirent, 525 struct linux_dirent64 __user *dirent,
526 unsigned int count); 526 unsigned int count);
527 #endif 527 #endif
528 asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, 528 asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
529 unsigned int nr_segs, unsigned int flags); 529 unsigned int nr_segs, unsigned int flags);
530 asmlinkage long compat_sys_open(const char __user *filename, int flags, 530 asmlinkage long compat_sys_open(const char __user *filename, int flags,
531 umode_t mode); 531 umode_t mode);
532 asmlinkage long compat_sys_openat(int dfd, const char __user *filename, 532 asmlinkage long compat_sys_openat(int dfd, const char __user *filename,
533 int flags, umode_t mode); 533 int flags, umode_t mode);
534 asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, 534 asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
535 struct file_handle __user *handle, 535 struct file_handle __user *handle,
536 int flags); 536 int flags);
537 asmlinkage long compat_sys_truncate(const char __user *, compat_off_t); 537 asmlinkage long compat_sys_truncate(const char __user *, compat_off_t);
538 asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t); 538 asmlinkage long compat_sys_ftruncate(unsigned int, compat_ulong_t);
539 asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, 539 asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
540 compat_ulong_t __user *outp, 540 compat_ulong_t __user *outp,
541 compat_ulong_t __user *exp, 541 compat_ulong_t __user *exp,
542 struct compat_timespec __user *tsp, 542 struct compat_timespec __user *tsp,
543 void __user *sig); 543 void __user *sig);
544 asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, 544 asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
545 unsigned int nfds, 545 unsigned int nfds,
546 struct compat_timespec __user *tsp, 546 struct compat_timespec __user *tsp,
547 const compat_sigset_t __user *sigmask, 547 const compat_sigset_t __user *sigmask,
548 compat_size_t sigsetsize); 548 compat_size_t sigsetsize);
549 asmlinkage long compat_sys_signalfd4(int ufd, 549 asmlinkage long compat_sys_signalfd4(int ufd,
550 const compat_sigset_t __user *sigmask, 550 const compat_sigset_t __user *sigmask,
551 compat_size_t sigsetsize, int flags); 551 compat_size_t sigsetsize, int flags);
552 asmlinkage long compat_sys_get_mempolicy(int __user *policy, 552 asmlinkage long compat_sys_get_mempolicy(int __user *policy,
553 compat_ulong_t __user *nmask, 553 compat_ulong_t __user *nmask,
554 compat_ulong_t maxnode, 554 compat_ulong_t maxnode,
555 compat_ulong_t addr, 555 compat_ulong_t addr,
556 compat_ulong_t flags); 556 compat_ulong_t flags);
557 asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, 557 asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
558 compat_ulong_t maxnode); 558 compat_ulong_t maxnode);
559 asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, 559 asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
560 compat_ulong_t mode, 560 compat_ulong_t mode,
561 compat_ulong_t __user *nmask, 561 compat_ulong_t __user *nmask,
562 compat_ulong_t maxnode, compat_ulong_t flags); 562 compat_ulong_t maxnode, compat_ulong_t flags);
563 563
564 asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, 564 asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
565 char __user *optval, unsigned int optlen); 565 char __user *optval, unsigned int optlen);
566 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, 566 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg,
567 unsigned flags); 567 unsigned flags);
568 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, 568 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
569 unsigned vlen, unsigned int flags); 569 unsigned vlen, unsigned int flags);
570 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, 570 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
571 unsigned int flags); 571 unsigned int flags);
572 asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, 572 asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len,
573 unsigned flags); 573 unsigned flags);
574 asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, 574 asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, compat_size_t len,
575 unsigned flags, struct sockaddr __user *addr, 575 unsigned flags, struct sockaddr __user *addr,
576 int __user *addrlen); 576 int __user *addrlen);
577 asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, 577 asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
578 unsigned vlen, unsigned int flags, 578 unsigned vlen, unsigned int flags,
579 struct compat_timespec __user *timeout); 579 struct compat_timespec __user *timeout);
580 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, 580 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
581 struct compat_timespec __user *rmtp); 581 struct compat_timespec __user *rmtp);
582 asmlinkage long compat_sys_getitimer(int which, 582 asmlinkage long compat_sys_getitimer(int which,
583 struct compat_itimerval __user *it); 583 struct compat_itimerval __user *it);
584 asmlinkage long compat_sys_setitimer(int which, 584 asmlinkage long compat_sys_setitimer(int which,
585 struct compat_itimerval __user *in, 585 struct compat_itimerval __user *in,
586 struct compat_itimerval __user *out); 586 struct compat_itimerval __user *out);
587 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf); 587 asmlinkage long compat_sys_times(struct compat_tms __user *tbuf);
588 asmlinkage long compat_sys_setrlimit(unsigned int resource, 588 asmlinkage long compat_sys_setrlimit(unsigned int resource,
589 struct compat_rlimit __user *rlim); 589 struct compat_rlimit __user *rlim);
590 asmlinkage long compat_sys_getrlimit(unsigned int resource, 590 asmlinkage long compat_sys_getrlimit(unsigned int resource,
591 struct compat_rlimit __user *rlim); 591 struct compat_rlimit __user *rlim);
592 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru); 592 asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru);
593 asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, 593 asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
594 unsigned int len, 594 unsigned int len,
595 compat_ulong_t __user *user_mask_ptr); 595 compat_ulong_t __user *user_mask_ptr);
596 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, 596 asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
597 unsigned int len, 597 unsigned int len,
598 compat_ulong_t __user *user_mask_ptr); 598 compat_ulong_t __user *user_mask_ptr);
599 asmlinkage long compat_sys_timer_create(clockid_t which_clock, 599 asmlinkage long compat_sys_timer_create(clockid_t which_clock,
600 struct compat_sigevent __user *timer_event_spec, 600 struct compat_sigevent __user *timer_event_spec,
601 timer_t __user *created_timer_id); 601 timer_t __user *created_timer_id);
602 asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags, 602 asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
603 struct compat_itimerspec __user *new, 603 struct compat_itimerspec __user *new,
604 struct compat_itimerspec __user *old); 604 struct compat_itimerspec __user *old);
605 asmlinkage long compat_sys_timer_gettime(timer_t timer_id, 605 asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
606 struct compat_itimerspec __user *setting); 606 struct compat_itimerspec __user *setting);
607 asmlinkage long compat_sys_clock_settime(clockid_t which_clock, 607 asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
608 struct compat_timespec __user *tp); 608 struct compat_timespec __user *tp);
609 asmlinkage long compat_sys_clock_gettime(clockid_t which_clock, 609 asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
610 struct compat_timespec __user *tp); 610 struct compat_timespec __user *tp);
611 asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock, 611 asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
612 struct compat_timex __user *tp); 612 struct compat_timex __user *tp);
613 asmlinkage long compat_sys_clock_getres(clockid_t which_clock, 613 asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
614 struct compat_timespec __user *tp); 614 struct compat_timespec __user *tp);
615 asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, 615 asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
616 struct compat_timespec __user *rqtp, 616 struct compat_timespec __user *rqtp,
617 struct compat_timespec __user *rmtp); 617 struct compat_timespec __user *rmtp);
618 asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese, 618 asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
619 struct compat_siginfo __user *uinfo, 619 struct compat_siginfo __user *uinfo,
620 struct compat_timespec __user *uts, compat_size_t sigsetsize); 620 struct compat_timespec __user *uts, compat_size_t sigsetsize);
621 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, 621 asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
622 compat_size_t sigsetsize); 622 compat_size_t sigsetsize);
623 asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, 623 asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
624 compat_sigset_t __user *oset, 624 compat_sigset_t __user *oset,
625 compat_size_t sigsetsize); 625 compat_size_t sigsetsize);
626 asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset, 626 asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
627 compat_size_t sigsetsize); 627 compat_size_t sigsetsize);
628 #ifndef CONFIG_ODD_RT_SIGACTION 628 #ifndef CONFIG_ODD_RT_SIGACTION
629 asmlinkage long compat_sys_rt_sigaction(int, 629 asmlinkage long compat_sys_rt_sigaction(int,
630 const struct compat_sigaction __user *, 630 const struct compat_sigaction __user *,
631 struct compat_sigaction __user *, 631 struct compat_sigaction __user *,
632 compat_size_t); 632 compat_size_t);
633 #endif 633 #endif
634 asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig, 634 asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
635 struct compat_siginfo __user *uinfo); 635 struct compat_siginfo __user *uinfo);
636 asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 636 asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
637 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 637 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
638 compat_ulong_t arg); 638 compat_ulong_t arg);
639 asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, 639 asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
640 struct compat_timespec __user *utime, u32 __user *uaddr2, 640 struct compat_timespec __user *utime, u32 __user *uaddr2,
641 u32 val3); 641 u32 val3);
642 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, 642 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
643 char __user *optval, int __user *optlen); 643 char __user *optval, int __user *optlen);
644 asmlinkage long compat_sys_kexec_load(unsigned long entry, 644 asmlinkage long compat_sys_kexec_load(unsigned long entry,
645 unsigned long nr_segments, 645 unsigned long nr_segments,
646 struct compat_kexec_segment __user *, 646 struct compat_kexec_segment __user *,
647 unsigned long flags); 647 unsigned long flags);
648 asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, 648 asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
649 const struct compat_mq_attr __user *u_mqstat, 649 const struct compat_mq_attr __user *u_mqstat,
650 struct compat_mq_attr __user *u_omqstat); 650 struct compat_mq_attr __user *u_omqstat);
651 asmlinkage long compat_sys_mq_notify(mqd_t mqdes, 651 asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
652 const struct compat_sigevent __user *u_notification); 652 const struct compat_sigevent __user *u_notification);
653 asmlinkage long compat_sys_mq_open(const char __user *u_name, 653 asmlinkage long compat_sys_mq_open(const char __user *u_name,
654 int oflag, compat_mode_t mode, 654 int oflag, compat_mode_t mode,
655 struct compat_mq_attr __user *u_attr); 655 struct compat_mq_attr __user *u_attr);
656 asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes, 656 asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
657 const char __user *u_msg_ptr, 657 const char __user *u_msg_ptr,
658 compat_size_t msg_len, unsigned int msg_prio, 658 compat_size_t msg_len, unsigned int msg_prio,
659 const struct compat_timespec __user *u_abs_timeout); 659 const struct compat_timespec __user *u_abs_timeout);
660 asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes, 660 asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
661 char __user *u_msg_ptr, 661 char __user *u_msg_ptr,
662 compat_size_t msg_len, unsigned int __user *u_msg_prio, 662 compat_size_t msg_len, unsigned int __user *u_msg_prio,
663 const struct compat_timespec __user *u_abs_timeout); 663 const struct compat_timespec __user *u_abs_timeout);
664 asmlinkage long compat_sys_socketcall(int call, u32 __user *args); 664 asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
665 asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args); 665 asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
666 666
667 extern ssize_t compat_rw_copy_check_uvector(int type, 667 extern ssize_t compat_rw_copy_check_uvector(int type,
668 const struct compat_iovec __user *uvector, 668 const struct compat_iovec __user *uvector,
669 unsigned long nr_segs, 669 unsigned long nr_segs,
670 unsigned long fast_segs, struct iovec *fast_pointer, 670 unsigned long fast_segs, struct iovec *fast_pointer,
671 struct iovec **ret_pointer); 671 struct iovec **ret_pointer);
672 672
673 extern void __user *compat_alloc_user_space(unsigned long len); 673 extern void __user *compat_alloc_user_space(unsigned long len);
674 674
675 asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, 675 asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
676 const struct compat_iovec __user *lvec, 676 const struct compat_iovec __user *lvec,
677 unsigned long liovcnt, const struct compat_iovec __user *rvec, 677 unsigned long liovcnt, const struct compat_iovec __user *rvec,
678 unsigned long riovcnt, unsigned long flags); 678 unsigned long riovcnt, unsigned long flags);
679 asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, 679 asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
680 const struct compat_iovec __user *lvec, 680 const struct compat_iovec __user *lvec,
681 unsigned long liovcnt, const struct compat_iovec __user *rvec, 681 unsigned long liovcnt, const struct compat_iovec __user *rvec,
682 unsigned long riovcnt, unsigned long flags); 682 unsigned long riovcnt, unsigned long flags);
683 683
684 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 684 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
685 compat_off_t __user *offset, compat_size_t count); 685 compat_off_t __user *offset, compat_size_t count);
686 asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, 686 asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
687 compat_loff_t __user *offset, compat_size_t count); 687 compat_loff_t __user *offset, compat_size_t count);
688 asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, 688 asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
689 compat_stack_t __user *uoss_ptr); 689 compat_stack_t __user *uoss_ptr);
690 690
691 int compat_restore_altstack(const compat_stack_t __user *uss); 691 int compat_restore_altstack(const compat_stack_t __user *uss);
692 int __compat_save_altstack(compat_stack_t __user *, unsigned long); 692 int __compat_save_altstack(compat_stack_t __user *, unsigned long);
693 #define compat_save_altstack_ex(uss, sp) do { \ 693 #define compat_save_altstack_ex(uss, sp) do { \
694 compat_stack_t __user *__uss = uss; \ 694 compat_stack_t __user *__uss = uss; \
695 struct task_struct *t = current; \ 695 struct task_struct *t = current; \
696 put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ 696 put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \
697 put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ 697 put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
698 put_user_ex(t->sas_ss_size, &__uss->ss_size); \ 698 put_user_ex(t->sas_ss_size, &__uss->ss_size); \
699 } while (0); 699 } while (0);
700 700
701 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, 701 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
702 struct compat_timespec __user *interval); 702 struct compat_timespec __user *interval);
703 703
704 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, 704 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
705 int, const char __user *); 705 int, const char __user *);
706 #else 706 #else
707 707
708 #define is_compat_task() (0) 708 #define is_compat_task() (0)
709 709
710 #endif /* CONFIG_COMPAT */ 710 #endif /* CONFIG_COMPAT */
711 #endif /* _LINUX_COMPAT_H */ 711 #endif /* _LINUX_COMPAT_H */
712 712
1 /* 1 /*
2 * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c. 2 * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c.
3 * 3 *
4 * Copyright (C) 2000 VA Linux Co 4 * Copyright (C) 2000 VA Linux Co
5 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com> 5 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
6 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com> 6 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
7 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 7 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 8 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
9 * Copyright (C) 2000 Hewlett-Packard Co. 9 * Copyright (C) 2000 Hewlett-Packard Co.
10 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> 10 * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
11 * Copyright (C) 2000,2001 Andi Kleen, SuSE Labs 11 * Copyright (C) 2000,2001 Andi Kleen, SuSE Labs
12 */ 12 */
13 13
14 #include <linux/kernel.h> 14 #include <linux/kernel.h>
15 #include <linux/gfp.h> 15 #include <linux/gfp.h>
16 #include <linux/fs.h> 16 #include <linux/fs.h>
17 #include <linux/types.h> 17 #include <linux/types.h>
18 #include <linux/file.h> 18 #include <linux/file.h>
19 #include <linux/icmpv6.h> 19 #include <linux/icmpv6.h>
20 #include <linux/socket.h> 20 #include <linux/socket.h>
21 #include <linux/syscalls.h> 21 #include <linux/syscalls.h>
22 #include <linux/filter.h> 22 #include <linux/filter.h>
23 #include <linux/compat.h> 23 #include <linux/compat.h>
24 #include <linux/security.h> 24 #include <linux/security.h>
25 #include <linux/export.h> 25 #include <linux/export.h>
26 26
27 #include <net/scm.h> 27 #include <net/scm.h>
28 #include <net/sock.h> 28 #include <net/sock.h>
29 #include <net/ip.h> 29 #include <net/ip.h>
30 #include <net/ipv6.h> 30 #include <net/ipv6.h>
31 #include <asm/uaccess.h> 31 #include <asm/uaccess.h>
32 #include <net/compat.h> 32 #include <net/compat.h>
33 33
34 static inline int iov_from_user_compat_to_kern(struct iovec *kiov, 34 static inline int iov_from_user_compat_to_kern(struct iovec *kiov,
35 struct compat_iovec __user *uiov32, 35 struct compat_iovec __user *uiov32,
36 int niov) 36 int niov)
37 { 37 {
38 int tot_len = 0; 38 int tot_len = 0;
39 39
40 while (niov > 0) { 40 while (niov > 0) {
41 compat_uptr_t buf; 41 compat_uptr_t buf;
42 compat_size_t len; 42 compat_size_t len;
43 43
44 if (get_user(len, &uiov32->iov_len) || 44 if (get_user(len, &uiov32->iov_len) ||
45 get_user(buf, &uiov32->iov_base)) 45 get_user(buf, &uiov32->iov_base))
46 return -EFAULT; 46 return -EFAULT;
47 47
48 if (len > INT_MAX - tot_len) 48 if (len > INT_MAX - tot_len)
49 len = INT_MAX - tot_len; 49 len = INT_MAX - tot_len;
50 50
51 tot_len += len; 51 tot_len += len;
52 kiov->iov_base = compat_ptr(buf); 52 kiov->iov_base = compat_ptr(buf);
53 kiov->iov_len = (__kernel_size_t) len; 53 kiov->iov_len = (__kernel_size_t) len;
54 uiov32++; 54 uiov32++;
55 kiov++; 55 kiov++;
56 niov--; 56 niov--;
57 } 57 }
58 return tot_len; 58 return tot_len;
59 } 59 }
60 60
61 int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) 61 int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
62 { 62 {
63 compat_uptr_t tmp1, tmp2, tmp3; 63 compat_uptr_t tmp1, tmp2, tmp3;
64 64
65 if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || 65 if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
66 __get_user(tmp1, &umsg->msg_name) || 66 __get_user(tmp1, &umsg->msg_name) ||
67 __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || 67 __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
68 __get_user(tmp2, &umsg->msg_iov) || 68 __get_user(tmp2, &umsg->msg_iov) ||
69 __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) || 69 __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
70 __get_user(tmp3, &umsg->msg_control) || 70 __get_user(tmp3, &umsg->msg_control) ||
71 __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || 71 __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
72 __get_user(kmsg->msg_flags, &umsg->msg_flags)) 72 __get_user(kmsg->msg_flags, &umsg->msg_flags))
73 return -EFAULT; 73 return -EFAULT;
74 if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) 74 if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
75 kmsg->msg_namelen = sizeof(struct sockaddr_storage); 75 kmsg->msg_namelen = sizeof(struct sockaddr_storage);
76 kmsg->msg_name = compat_ptr(tmp1); 76 kmsg->msg_name = compat_ptr(tmp1);
77 kmsg->msg_iov = compat_ptr(tmp2); 77 kmsg->msg_iov = compat_ptr(tmp2);
78 kmsg->msg_control = compat_ptr(tmp3); 78 kmsg->msg_control = compat_ptr(tmp3);
79 return 0; 79 return 0;
80 } 80 }
81 81
82 /* I've named the args so it is easy to tell whose space the pointers are in. */ 82 /* I've named the args so it is easy to tell whose space the pointers are in. */
83 int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, 83 int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
84 struct sockaddr_storage *kern_address, int mode) 84 struct sockaddr_storage *kern_address, int mode)
85 { 85 {
86 int tot_len; 86 int tot_len;
87 87
88 if (kern_msg->msg_namelen) { 88 if (kern_msg->msg_namelen) {
89 if (mode == VERIFY_READ) { 89 if (mode == VERIFY_READ) {
90 int err = move_addr_to_kernel(kern_msg->msg_name, 90 int err = move_addr_to_kernel(kern_msg->msg_name,
91 kern_msg->msg_namelen, 91 kern_msg->msg_namelen,
92 kern_address); 92 kern_address);
93 if (err < 0) 93 if (err < 0)
94 return err; 94 return err;
95 } 95 }
96 if (kern_msg->msg_name) 96 if (kern_msg->msg_name)
97 kern_msg->msg_name = kern_address; 97 kern_msg->msg_name = kern_address;
98 } else 98 } else
99 kern_msg->msg_name = NULL; 99 kern_msg->msg_name = NULL;
100 100
101 tot_len = iov_from_user_compat_to_kern(kern_iov, 101 tot_len = iov_from_user_compat_to_kern(kern_iov,
102 (struct compat_iovec __user *)kern_msg->msg_iov, 102 (struct compat_iovec __user *)kern_msg->msg_iov,
103 kern_msg->msg_iovlen); 103 kern_msg->msg_iovlen);
104 if (tot_len >= 0) 104 if (tot_len >= 0)
105 kern_msg->msg_iov = kern_iov; 105 kern_msg->msg_iov = kern_iov;
106 106
107 return tot_len; 107 return tot_len;
108 } 108 }
109 109
110 /* Bleech... */ 110 /* Bleech... */
111 #define CMSG_COMPAT_ALIGN(len) ALIGN((len), sizeof(s32)) 111 #define CMSG_COMPAT_ALIGN(len) ALIGN((len), sizeof(s32))
112 112
113 #define CMSG_COMPAT_DATA(cmsg) \ 113 #define CMSG_COMPAT_DATA(cmsg) \
114 ((void __user *)((char __user *)(cmsg) + CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)))) 114 ((void __user *)((char __user *)(cmsg) + CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr))))
115 #define CMSG_COMPAT_SPACE(len) \ 115 #define CMSG_COMPAT_SPACE(len) \
116 (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + CMSG_COMPAT_ALIGN(len)) 116 (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + CMSG_COMPAT_ALIGN(len))
117 #define CMSG_COMPAT_LEN(len) \ 117 #define CMSG_COMPAT_LEN(len) \
118 (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + (len)) 118 (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + (len))
119 119
120 #define CMSG_COMPAT_FIRSTHDR(msg) \ 120 #define CMSG_COMPAT_FIRSTHDR(msg) \
121 (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \ 121 (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \
122 (struct compat_cmsghdr __user *)((msg)->msg_control) : \ 122 (struct compat_cmsghdr __user *)((msg)->msg_control) : \
123 (struct compat_cmsghdr __user *)NULL) 123 (struct compat_cmsghdr __user *)NULL)
124 124
125 #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \ 125 #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
126 ((ucmlen) >= sizeof(struct compat_cmsghdr) && \ 126 ((ucmlen) >= sizeof(struct compat_cmsghdr) && \
127 (ucmlen) <= (unsigned long) \ 127 (ucmlen) <= (unsigned long) \
128 ((mhdr)->msg_controllen - \ 128 ((mhdr)->msg_controllen - \
129 ((char *)(ucmsg) - (char *)(mhdr)->msg_control))) 129 ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
130 130
131 static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg, 131 static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
132 struct compat_cmsghdr __user *cmsg, int cmsg_len) 132 struct compat_cmsghdr __user *cmsg, int cmsg_len)
133 { 133 {
134 char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len); 134 char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
135 if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) > 135 if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) >
136 msg->msg_controllen) 136 msg->msg_controllen)
137 return NULL; 137 return NULL;
138 return (struct compat_cmsghdr __user *)ptr; 138 return (struct compat_cmsghdr __user *)ptr;
139 } 139 }
140 140
141 /* There is a lot of hair here because the alignment rules (and 141 /* There is a lot of hair here because the alignment rules (and
142 * thus placement) of cmsg headers and length are different for 142 * thus placement) of cmsg headers and length are different for
143 * 32-bit apps. -DaveM 143 * 32-bit apps. -DaveM
144 */ 144 */
145 int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk, 145 int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
146 unsigned char *stackbuf, int stackbuf_size) 146 unsigned char *stackbuf, int stackbuf_size)
147 { 147 {
148 struct compat_cmsghdr __user *ucmsg; 148 struct compat_cmsghdr __user *ucmsg;
149 struct cmsghdr *kcmsg, *kcmsg_base; 149 struct cmsghdr *kcmsg, *kcmsg_base;
150 compat_size_t ucmlen; 150 compat_size_t ucmlen;
151 __kernel_size_t kcmlen, tmp; 151 __kernel_size_t kcmlen, tmp;
152 int err = -EFAULT; 152 int err = -EFAULT;
153 153
154 kcmlen = 0; 154 kcmlen = 0;
155 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf; 155 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
156 ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg); 156 ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
157 while (ucmsg != NULL) { 157 while (ucmsg != NULL) {
158 if (get_user(ucmlen, &ucmsg->cmsg_len)) 158 if (get_user(ucmlen, &ucmsg->cmsg_len))
159 return -EFAULT; 159 return -EFAULT;
160 160
161 /* Catch bogons. */ 161 /* Catch bogons. */
162 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg)) 162 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
163 return -EINVAL; 163 return -EINVAL;
164 164
165 tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) + 165 tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
166 CMSG_ALIGN(sizeof(struct cmsghdr))); 166 CMSG_ALIGN(sizeof(struct cmsghdr)));
167 tmp = CMSG_ALIGN(tmp); 167 tmp = CMSG_ALIGN(tmp);
168 kcmlen += tmp; 168 kcmlen += tmp;
169 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen); 169 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
170 } 170 }
171 if (kcmlen == 0) 171 if (kcmlen == 0)
172 return -EINVAL; 172 return -EINVAL;
173 173
174 /* The kcmlen holds the 64-bit version of the control length. 174 /* The kcmlen holds the 64-bit version of the control length.
175 * It may not be modified as we do not stick it into the kmsg 175 * It may not be modified as we do not stick it into the kmsg
176 * until we have successfully copied over all of the data 176 * until we have successfully copied over all of the data
177 * from the user. 177 * from the user.
178 */ 178 */
179 if (kcmlen > stackbuf_size) 179 if (kcmlen > stackbuf_size)
180 kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL); 180 kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
181 if (kcmsg == NULL) 181 if (kcmsg == NULL)
182 return -ENOBUFS; 182 return -ENOBUFS;
183 183
184 /* Now copy them over neatly. */ 184 /* Now copy them over neatly. */
185 memset(kcmsg, 0, kcmlen); 185 memset(kcmsg, 0, kcmlen);
186 ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg); 186 ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
187 while (ucmsg != NULL) { 187 while (ucmsg != NULL) {
188 if (__get_user(ucmlen, &ucmsg->cmsg_len)) 188 if (__get_user(ucmlen, &ucmsg->cmsg_len))
189 goto Efault; 189 goto Efault;
190 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg)) 190 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
191 goto Einval; 191 goto Einval;
192 tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) + 192 tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
193 CMSG_ALIGN(sizeof(struct cmsghdr))); 193 CMSG_ALIGN(sizeof(struct cmsghdr)));
194 if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp)) 194 if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
195 goto Einval; 195 goto Einval;
196 kcmsg->cmsg_len = tmp; 196 kcmsg->cmsg_len = tmp;
197 tmp = CMSG_ALIGN(tmp); 197 tmp = CMSG_ALIGN(tmp);
198 if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) || 198 if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
199 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) || 199 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
200 copy_from_user(CMSG_DATA(kcmsg), 200 copy_from_user(CMSG_DATA(kcmsg),
201 CMSG_COMPAT_DATA(ucmsg), 201 CMSG_COMPAT_DATA(ucmsg),
202 (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))))) 202 (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
203 goto Efault; 203 goto Efault;
204 204
205 /* Advance. */ 205 /* Advance. */
206 kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp); 206 kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
207 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen); 207 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
208 } 208 }
209 209
210 /* Ok, looks like we made it. Hook it up and return success. */ 210 /* Ok, looks like we made it. Hook it up and return success. */
211 kmsg->msg_control = kcmsg_base; 211 kmsg->msg_control = kcmsg_base;
212 kmsg->msg_controllen = kcmlen; 212 kmsg->msg_controllen = kcmlen;
213 return 0; 213 return 0;
214 214
215 Einval: 215 Einval:
216 err = -EINVAL; 216 err = -EINVAL;
217 Efault: 217 Efault:
218 if (kcmsg_base != (struct cmsghdr *)stackbuf) 218 if (kcmsg_base != (struct cmsghdr *)stackbuf)
219 sock_kfree_s(sk, kcmsg_base, kcmlen); 219 sock_kfree_s(sk, kcmsg_base, kcmlen);
220 return err; 220 return err;
221 } 221 }
222 222
223 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data) 223 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
224 { 224 {
225 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; 225 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
226 struct compat_cmsghdr cmhdr; 226 struct compat_cmsghdr cmhdr;
227 struct compat_timeval ctv; 227 struct compat_timeval ctv;
228 struct compat_timespec cts[3]; 228 struct compat_timespec cts[3];
229 int cmlen; 229 int cmlen;
230 230
231 if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) { 231 if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
232 kmsg->msg_flags |= MSG_CTRUNC; 232 kmsg->msg_flags |= MSG_CTRUNC;
233 return 0; /* XXX: return error? check spec. */ 233 return 0; /* XXX: return error? check spec. */
234 } 234 }
235 235
236 if (!COMPAT_USE_64BIT_TIME) { 236 if (!COMPAT_USE_64BIT_TIME) {
237 if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { 237 if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
238 struct timeval *tv = (struct timeval *)data; 238 struct timeval *tv = (struct timeval *)data;
239 ctv.tv_sec = tv->tv_sec; 239 ctv.tv_sec = tv->tv_sec;
240 ctv.tv_usec = tv->tv_usec; 240 ctv.tv_usec = tv->tv_usec;
241 data = &ctv; 241 data = &ctv;
242 len = sizeof(ctv); 242 len = sizeof(ctv);
243 } 243 }
244 if (level == SOL_SOCKET && 244 if (level == SOL_SOCKET &&
245 (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) { 245 (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
246 int count = type == SCM_TIMESTAMPNS ? 1 : 3; 246 int count = type == SCM_TIMESTAMPNS ? 1 : 3;
247 int i; 247 int i;
248 struct timespec *ts = (struct timespec *)data; 248 struct timespec *ts = (struct timespec *)data;
249 for (i = 0; i < count; i++) { 249 for (i = 0; i < count; i++) {
250 cts[i].tv_sec = ts[i].tv_sec; 250 cts[i].tv_sec = ts[i].tv_sec;
251 cts[i].tv_nsec = ts[i].tv_nsec; 251 cts[i].tv_nsec = ts[i].tv_nsec;
252 } 252 }
253 data = &cts; 253 data = &cts;
254 len = sizeof(cts[0]) * count; 254 len = sizeof(cts[0]) * count;
255 } 255 }
256 } 256 }
257 257
258 cmlen = CMSG_COMPAT_LEN(len); 258 cmlen = CMSG_COMPAT_LEN(len);
259 if (kmsg->msg_controllen < cmlen) { 259 if (kmsg->msg_controllen < cmlen) {
260 kmsg->msg_flags |= MSG_CTRUNC; 260 kmsg->msg_flags |= MSG_CTRUNC;
261 cmlen = kmsg->msg_controllen; 261 cmlen = kmsg->msg_controllen;
262 } 262 }
263 cmhdr.cmsg_level = level; 263 cmhdr.cmsg_level = level;
264 cmhdr.cmsg_type = type; 264 cmhdr.cmsg_type = type;
265 cmhdr.cmsg_len = cmlen; 265 cmhdr.cmsg_len = cmlen;
266 266
267 if (copy_to_user(cm, &cmhdr, sizeof cmhdr)) 267 if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
268 return -EFAULT; 268 return -EFAULT;
269 if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr))) 269 if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
270 return -EFAULT; 270 return -EFAULT;
271 cmlen = CMSG_COMPAT_SPACE(len); 271 cmlen = CMSG_COMPAT_SPACE(len);
272 if (kmsg->msg_controllen < cmlen) 272 if (kmsg->msg_controllen < cmlen)
273 cmlen = kmsg->msg_controllen; 273 cmlen = kmsg->msg_controllen;
274 kmsg->msg_control += cmlen; 274 kmsg->msg_control += cmlen;
275 kmsg->msg_controllen -= cmlen; 275 kmsg->msg_controllen -= cmlen;
276 return 0; 276 return 0;
277 } 277 }
278 278
279 void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) 279 void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
280 { 280 {
281 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; 281 struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
282 int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int); 282 int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
283 int fdnum = scm->fp->count; 283 int fdnum = scm->fp->count;
284 struct file **fp = scm->fp->fp; 284 struct file **fp = scm->fp->fp;
285 int __user *cmfptr; 285 int __user *cmfptr;
286 int err = 0, i; 286 int err = 0, i;
287 287
288 if (fdnum < fdmax) 288 if (fdnum < fdmax)
289 fdmax = fdnum; 289 fdmax = fdnum;
290 290
291 for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) { 291 for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) {
292 int new_fd; 292 int new_fd;
293 err = security_file_receive(fp[i]); 293 err = security_file_receive(fp[i]);
294 if (err) 294 if (err)
295 break; 295 break;
296 err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags 296 err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags
297 ? O_CLOEXEC : 0); 297 ? O_CLOEXEC : 0);
298 if (err < 0) 298 if (err < 0)
299 break; 299 break;
300 new_fd = err; 300 new_fd = err;
301 err = put_user(new_fd, cmfptr); 301 err = put_user(new_fd, cmfptr);
302 if (err) { 302 if (err) {
303 put_unused_fd(new_fd); 303 put_unused_fd(new_fd);
304 break; 304 break;
305 } 305 }
306 /* Bump the usage count and install the file. */ 306 /* Bump the usage count and install the file. */
307 fd_install(new_fd, get_file(fp[i])); 307 fd_install(new_fd, get_file(fp[i]));
308 } 308 }
309 309
310 if (i > 0) { 310 if (i > 0) {
311 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); 311 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
312 err = put_user(SOL_SOCKET, &cm->cmsg_level); 312 err = put_user(SOL_SOCKET, &cm->cmsg_level);
313 if (!err) 313 if (!err)
314 err = put_user(SCM_RIGHTS, &cm->cmsg_type); 314 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
315 if (!err) 315 if (!err)
316 err = put_user(cmlen, &cm->cmsg_len); 316 err = put_user(cmlen, &cm->cmsg_len);
317 if (!err) { 317 if (!err) {
318 cmlen = CMSG_COMPAT_SPACE(i * sizeof(int)); 318 cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
319 kmsg->msg_control += cmlen; 319 kmsg->msg_control += cmlen;
320 kmsg->msg_controllen -= cmlen; 320 kmsg->msg_controllen -= cmlen;
321 } 321 }
322 } 322 }
323 if (i < fdnum) 323 if (i < fdnum)
324 kmsg->msg_flags |= MSG_CTRUNC; 324 kmsg->msg_flags |= MSG_CTRUNC;
325 325
326 /* 326 /*
327 * All of the files that fit in the message have had their 327 * All of the files that fit in the message have had their
328 * usage counts incremented, so we just free the list. 328 * usage counts incremented, so we just free the list.
329 */ 329 */
330 __scm_destroy(scm); 330 __scm_destroy(scm);
331 } 331 }
332 332
333 static int do_set_attach_filter(struct socket *sock, int level, int optname, 333 static int do_set_attach_filter(struct socket *sock, int level, int optname,
334 char __user *optval, unsigned int optlen) 334 char __user *optval, unsigned int optlen)
335 { 335 {
336 struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; 336 struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
337 struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); 337 struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
338 compat_uptr_t ptr; 338 compat_uptr_t ptr;
339 u16 len; 339 u16 len;
340 340
341 if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) || 341 if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) ||
342 !access_ok(VERIFY_WRITE, kfprog, sizeof(struct sock_fprog)) || 342 !access_ok(VERIFY_WRITE, kfprog, sizeof(struct sock_fprog)) ||
343 __get_user(len, &fprog32->len) || 343 __get_user(len, &fprog32->len) ||
344 __get_user(ptr, &fprog32->filter) || 344 __get_user(ptr, &fprog32->filter) ||
345 __put_user(len, &kfprog->len) || 345 __put_user(len, &kfprog->len) ||
346 __put_user(compat_ptr(ptr), &kfprog->filter)) 346 __put_user(compat_ptr(ptr), &kfprog->filter))
347 return -EFAULT; 347 return -EFAULT;
348 348
349 return sock_setsockopt(sock, level, optname, (char __user *)kfprog, 349 return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
350 sizeof(struct sock_fprog)); 350 sizeof(struct sock_fprog));
351 } 351 }
352 352
353 static int do_set_sock_timeout(struct socket *sock, int level, 353 static int do_set_sock_timeout(struct socket *sock, int level,
354 int optname, char __user *optval, unsigned int optlen) 354 int optname, char __user *optval, unsigned int optlen)
355 { 355 {
356 struct compat_timeval __user *up = (struct compat_timeval __user *)optval; 356 struct compat_timeval __user *up = (struct compat_timeval __user *)optval;
357 struct timeval ktime; 357 struct timeval ktime;
358 mm_segment_t old_fs; 358 mm_segment_t old_fs;
359 int err; 359 int err;
360 360
361 if (optlen < sizeof(*up)) 361 if (optlen < sizeof(*up))
362 return -EINVAL; 362 return -EINVAL;
363 if (!access_ok(VERIFY_READ, up, sizeof(*up)) || 363 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
364 __get_user(ktime.tv_sec, &up->tv_sec) || 364 __get_user(ktime.tv_sec, &up->tv_sec) ||
365 __get_user(ktime.tv_usec, &up->tv_usec)) 365 __get_user(ktime.tv_usec, &up->tv_usec))
366 return -EFAULT; 366 return -EFAULT;
367 old_fs = get_fs(); 367 old_fs = get_fs();
368 set_fs(KERNEL_DS); 368 set_fs(KERNEL_DS);
369 err = sock_setsockopt(sock, level, optname, (char *)&ktime, sizeof(ktime)); 369 err = sock_setsockopt(sock, level, optname, (char *)&ktime, sizeof(ktime));
370 set_fs(old_fs); 370 set_fs(old_fs);
371 371
372 return err; 372 return err;
373 } 373 }
374 374
375 static int compat_sock_setsockopt(struct socket *sock, int level, int optname, 375 static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
376 char __user *optval, unsigned int optlen) 376 char __user *optval, unsigned int optlen)
377 { 377 {
378 if (optname == SO_ATTACH_FILTER) 378 if (optname == SO_ATTACH_FILTER)
379 return do_set_attach_filter(sock, level, optname, 379 return do_set_attach_filter(sock, level, optname,
380 optval, optlen); 380 optval, optlen);
381 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) 381 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
382 return do_set_sock_timeout(sock, level, optname, optval, optlen); 382 return do_set_sock_timeout(sock, level, optname, optval, optlen);
383 383
384 return sock_setsockopt(sock, level, optname, optval, optlen); 384 return sock_setsockopt(sock, level, optname, optval, optlen);
385 } 385 }
386 386
387 COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, 387 COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
388 char __user *, optval, unsigned int, optlen) 388 char __user *, optval, unsigned int, optlen)
389 { 389 {
390 int err; 390 int err;
391 struct socket *sock = sockfd_lookup(fd, &err); 391 struct socket *sock = sockfd_lookup(fd, &err);
392 392
393 if (sock) { 393 if (sock) {
394 err = security_socket_setsockopt(sock, level, optname); 394 err = security_socket_setsockopt(sock, level, optname);
395 if (err) { 395 if (err) {
396 sockfd_put(sock); 396 sockfd_put(sock);
397 return err; 397 return err;
398 } 398 }
399 399
400 if (level == SOL_SOCKET) 400 if (level == SOL_SOCKET)
401 err = compat_sock_setsockopt(sock, level, 401 err = compat_sock_setsockopt(sock, level,
402 optname, optval, optlen); 402 optname, optval, optlen);
403 else if (sock->ops->compat_setsockopt) 403 else if (sock->ops->compat_setsockopt)
404 err = sock->ops->compat_setsockopt(sock, level, 404 err = sock->ops->compat_setsockopt(sock, level,
405 optname, optval, optlen); 405 optname, optval, optlen);
406 else 406 else
407 err = sock->ops->setsockopt(sock, level, 407 err = sock->ops->setsockopt(sock, level,
408 optname, optval, optlen); 408 optname, optval, optlen);
409 sockfd_put(sock); 409 sockfd_put(sock);
410 } 410 }
411 return err; 411 return err;
412 } 412 }
413 413
414 static int do_get_sock_timeout(struct socket *sock, int level, int optname, 414 static int do_get_sock_timeout(struct socket *sock, int level, int optname,
415 char __user *optval, int __user *optlen) 415 char __user *optval, int __user *optlen)
416 { 416 {
417 struct compat_timeval __user *up; 417 struct compat_timeval __user *up;
418 struct timeval ktime; 418 struct timeval ktime;
419 mm_segment_t old_fs; 419 mm_segment_t old_fs;
420 int len, err; 420 int len, err;
421 421
422 up = (struct compat_timeval __user *) optval; 422 up = (struct compat_timeval __user *) optval;
423 if (get_user(len, optlen)) 423 if (get_user(len, optlen))
424 return -EFAULT; 424 return -EFAULT;
425 if (len < sizeof(*up)) 425 if (len < sizeof(*up))
426 return -EINVAL; 426 return -EINVAL;
427 len = sizeof(ktime); 427 len = sizeof(ktime);
428 old_fs = get_fs(); 428 old_fs = get_fs();
429 set_fs(KERNEL_DS); 429 set_fs(KERNEL_DS);
430 err = sock_getsockopt(sock, level, optname, (char *) &ktime, &len); 430 err = sock_getsockopt(sock, level, optname, (char *) &ktime, &len);
431 set_fs(old_fs); 431 set_fs(old_fs);
432 432
433 if (!err) { 433 if (!err) {
434 if (put_user(sizeof(*up), optlen) || 434 if (put_user(sizeof(*up), optlen) ||
435 !access_ok(VERIFY_WRITE, up, sizeof(*up)) || 435 !access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
436 __put_user(ktime.tv_sec, &up->tv_sec) || 436 __put_user(ktime.tv_sec, &up->tv_sec) ||
437 __put_user(ktime.tv_usec, &up->tv_usec)) 437 __put_user(ktime.tv_usec, &up->tv_usec))
438 err = -EFAULT; 438 err = -EFAULT;
439 } 439 }
440 return err; 440 return err;
441 } 441 }
442 442
443 static int compat_sock_getsockopt(struct socket *sock, int level, int optname, 443 static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
444 char __user *optval, int __user *optlen) 444 char __user *optval, int __user *optlen)
445 { 445 {
446 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) 446 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
447 return do_get_sock_timeout(sock, level, optname, optval, optlen); 447 return do_get_sock_timeout(sock, level, optname, optval, optlen);
448 return sock_getsockopt(sock, level, optname, optval, optlen); 448 return sock_getsockopt(sock, level, optname, optval, optlen);
449 } 449 }
450 450
451 int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) 451 int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
452 { 452 {
453 struct compat_timeval __user *ctv; 453 struct compat_timeval __user *ctv;
454 int err; 454 int err;
455 struct timeval tv; 455 struct timeval tv;
456 456
457 if (COMPAT_USE_64BIT_TIME) 457 if (COMPAT_USE_64BIT_TIME)
458 return sock_get_timestamp(sk, userstamp); 458 return sock_get_timestamp(sk, userstamp);
459 459
460 ctv = (struct compat_timeval __user *) userstamp; 460 ctv = (struct compat_timeval __user *) userstamp;
461 err = -ENOENT; 461 err = -ENOENT;
462 if (!sock_flag(sk, SOCK_TIMESTAMP)) 462 if (!sock_flag(sk, SOCK_TIMESTAMP))
463 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 463 sock_enable_timestamp(sk, SOCK_TIMESTAMP);
464 tv = ktime_to_timeval(sk->sk_stamp); 464 tv = ktime_to_timeval(sk->sk_stamp);
465 if (tv.tv_sec == -1) 465 if (tv.tv_sec == -1)
466 return err; 466 return err;
467 if (tv.tv_sec == 0) { 467 if (tv.tv_sec == 0) {
468 sk->sk_stamp = ktime_get_real(); 468 sk->sk_stamp = ktime_get_real();
469 tv = ktime_to_timeval(sk->sk_stamp); 469 tv = ktime_to_timeval(sk->sk_stamp);
470 } 470 }
471 err = 0; 471 err = 0;
472 if (put_user(tv.tv_sec, &ctv->tv_sec) || 472 if (put_user(tv.tv_sec, &ctv->tv_sec) ||
473 put_user(tv.tv_usec, &ctv->tv_usec)) 473 put_user(tv.tv_usec, &ctv->tv_usec))
474 err = -EFAULT; 474 err = -EFAULT;
475 return err; 475 return err;
476 } 476 }
477 EXPORT_SYMBOL(compat_sock_get_timestamp); 477 EXPORT_SYMBOL(compat_sock_get_timestamp);
478 478
479 int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) 479 int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
480 { 480 {
481 struct compat_timespec __user *ctv; 481 struct compat_timespec __user *ctv;
482 int err; 482 int err;
483 struct timespec ts; 483 struct timespec ts;
484 484
485 if (COMPAT_USE_64BIT_TIME) 485 if (COMPAT_USE_64BIT_TIME)
486 return sock_get_timestampns (sk, userstamp); 486 return sock_get_timestampns (sk, userstamp);
487 487
488 ctv = (struct compat_timespec __user *) userstamp; 488 ctv = (struct compat_timespec __user *) userstamp;
489 err = -ENOENT; 489 err = -ENOENT;
490 if (!sock_flag(sk, SOCK_TIMESTAMP)) 490 if (!sock_flag(sk, SOCK_TIMESTAMP))
491 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 491 sock_enable_timestamp(sk, SOCK_TIMESTAMP);
492 ts = ktime_to_timespec(sk->sk_stamp); 492 ts = ktime_to_timespec(sk->sk_stamp);
493 if (ts.tv_sec == -1) 493 if (ts.tv_sec == -1)
494 return err; 494 return err;
495 if (ts.tv_sec == 0) { 495 if (ts.tv_sec == 0) {
496 sk->sk_stamp = ktime_get_real(); 496 sk->sk_stamp = ktime_get_real();
497 ts = ktime_to_timespec(sk->sk_stamp); 497 ts = ktime_to_timespec(sk->sk_stamp);
498 } 498 }
499 err = 0; 499 err = 0;
500 if (put_user(ts.tv_sec, &ctv->tv_sec) || 500 if (put_user(ts.tv_sec, &ctv->tv_sec) ||
501 put_user(ts.tv_nsec, &ctv->tv_nsec)) 501 put_user(ts.tv_nsec, &ctv->tv_nsec))
502 err = -EFAULT; 502 err = -EFAULT;
503 return err; 503 return err;
504 } 504 }
505 EXPORT_SYMBOL(compat_sock_get_timestampns); 505 EXPORT_SYMBOL(compat_sock_get_timestampns);
506 506
507 COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, 507 COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
508 char __user *, optval, int __user *, optlen) 508 char __user *, optval, int __user *, optlen)
509 { 509 {
510 int err; 510 int err;
511 struct socket *sock = sockfd_lookup(fd, &err); 511 struct socket *sock = sockfd_lookup(fd, &err);
512 512
513 if (sock) { 513 if (sock) {
514 err = security_socket_getsockopt(sock, level, optname); 514 err = security_socket_getsockopt(sock, level, optname);
515 if (err) { 515 if (err) {
516 sockfd_put(sock); 516 sockfd_put(sock);
517 return err; 517 return err;
518 } 518 }
519 519
520 if (level == SOL_SOCKET) 520 if (level == SOL_SOCKET)
521 err = compat_sock_getsockopt(sock, level, 521 err = compat_sock_getsockopt(sock, level,
522 optname, optval, optlen); 522 optname, optval, optlen);
523 else if (sock->ops->compat_getsockopt) 523 else if (sock->ops->compat_getsockopt)
524 err = sock->ops->compat_getsockopt(sock, level, 524 err = sock->ops->compat_getsockopt(sock, level,
525 optname, optval, optlen); 525 optname, optval, optlen);
526 else 526 else
527 err = sock->ops->getsockopt(sock, level, 527 err = sock->ops->getsockopt(sock, level,
528 optname, optval, optlen); 528 optname, optval, optlen);
529 sockfd_put(sock); 529 sockfd_put(sock);
530 } 530 }
531 return err; 531 return err;
532 } 532 }
533 533
534 struct compat_group_req { 534 struct compat_group_req {
535 __u32 gr_interface; 535 __u32 gr_interface;
536 struct __kernel_sockaddr_storage gr_group 536 struct __kernel_sockaddr_storage gr_group
537 __attribute__ ((aligned(4))); 537 __attribute__ ((aligned(4)));
538 } __packed; 538 } __packed;
539 539
540 struct compat_group_source_req { 540 struct compat_group_source_req {
541 __u32 gsr_interface; 541 __u32 gsr_interface;
542 struct __kernel_sockaddr_storage gsr_group 542 struct __kernel_sockaddr_storage gsr_group
543 __attribute__ ((aligned(4))); 543 __attribute__ ((aligned(4)));
544 struct __kernel_sockaddr_storage gsr_source 544 struct __kernel_sockaddr_storage gsr_source
545 __attribute__ ((aligned(4))); 545 __attribute__ ((aligned(4)));
546 } __packed; 546 } __packed;
547 547
548 struct compat_group_filter { 548 struct compat_group_filter {
549 __u32 gf_interface; 549 __u32 gf_interface;
550 struct __kernel_sockaddr_storage gf_group 550 struct __kernel_sockaddr_storage gf_group
551 __attribute__ ((aligned(4))); 551 __attribute__ ((aligned(4)));
552 __u32 gf_fmode; 552 __u32 gf_fmode;
553 __u32 gf_numsrc; 553 __u32 gf_numsrc;
554 struct __kernel_sockaddr_storage gf_slist[1] 554 struct __kernel_sockaddr_storage gf_slist[1]
555 __attribute__ ((aligned(4))); 555 __attribute__ ((aligned(4)));
556 } __packed; 556 } __packed;
557 557
558 #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ 558 #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \
559 sizeof(struct __kernel_sockaddr_storage)) 559 sizeof(struct __kernel_sockaddr_storage))
560 560
561 561
562 int compat_mc_setsockopt(struct sock *sock, int level, int optname, 562 int compat_mc_setsockopt(struct sock *sock, int level, int optname,
563 char __user *optval, unsigned int optlen, 563 char __user *optval, unsigned int optlen,
564 int (*setsockopt)(struct sock *, int, int, char __user *, unsigned int)) 564 int (*setsockopt)(struct sock *, int, int, char __user *, unsigned int))
565 { 565 {
566 char __user *koptval = optval; 566 char __user *koptval = optval;
567 int koptlen = optlen; 567 int koptlen = optlen;
568 568
569 switch (optname) { 569 switch (optname) {
570 case MCAST_JOIN_GROUP: 570 case MCAST_JOIN_GROUP:
571 case MCAST_LEAVE_GROUP: 571 case MCAST_LEAVE_GROUP:
572 { 572 {
573 struct compat_group_req __user *gr32 = (void *)optval; 573 struct compat_group_req __user *gr32 = (void *)optval;
574 struct group_req __user *kgr = 574 struct group_req __user *kgr =
575 compat_alloc_user_space(sizeof(struct group_req)); 575 compat_alloc_user_space(sizeof(struct group_req));
576 u32 interface; 576 u32 interface;
577 577
578 if (!access_ok(VERIFY_READ, gr32, sizeof(*gr32)) || 578 if (!access_ok(VERIFY_READ, gr32, sizeof(*gr32)) ||
579 !access_ok(VERIFY_WRITE, kgr, sizeof(struct group_req)) || 579 !access_ok(VERIFY_WRITE, kgr, sizeof(struct group_req)) ||
580 __get_user(interface, &gr32->gr_interface) || 580 __get_user(interface, &gr32->gr_interface) ||
581 __put_user(interface, &kgr->gr_interface) || 581 __put_user(interface, &kgr->gr_interface) ||
582 copy_in_user(&kgr->gr_group, &gr32->gr_group, 582 copy_in_user(&kgr->gr_group, &gr32->gr_group,
583 sizeof(kgr->gr_group))) 583 sizeof(kgr->gr_group)))
584 return -EFAULT; 584 return -EFAULT;
585 koptval = (char __user *)kgr; 585 koptval = (char __user *)kgr;
586 koptlen = sizeof(struct group_req); 586 koptlen = sizeof(struct group_req);
587 break; 587 break;
588 } 588 }
589 case MCAST_JOIN_SOURCE_GROUP: 589 case MCAST_JOIN_SOURCE_GROUP:
590 case MCAST_LEAVE_SOURCE_GROUP: 590 case MCAST_LEAVE_SOURCE_GROUP:
591 case MCAST_BLOCK_SOURCE: 591 case MCAST_BLOCK_SOURCE:
592 case MCAST_UNBLOCK_SOURCE: 592 case MCAST_UNBLOCK_SOURCE:
593 { 593 {
594 struct compat_group_source_req __user *gsr32 = (void *)optval; 594 struct compat_group_source_req __user *gsr32 = (void *)optval;
595 struct group_source_req __user *kgsr = compat_alloc_user_space( 595 struct group_source_req __user *kgsr = compat_alloc_user_space(
596 sizeof(struct group_source_req)); 596 sizeof(struct group_source_req));
597 u32 interface; 597 u32 interface;
598 598
599 if (!access_ok(VERIFY_READ, gsr32, sizeof(*gsr32)) || 599 if (!access_ok(VERIFY_READ, gsr32, sizeof(*gsr32)) ||
600 !access_ok(VERIFY_WRITE, kgsr, 600 !access_ok(VERIFY_WRITE, kgsr,
601 sizeof(struct group_source_req)) || 601 sizeof(struct group_source_req)) ||
602 __get_user(interface, &gsr32->gsr_interface) || 602 __get_user(interface, &gsr32->gsr_interface) ||
603 __put_user(interface, &kgsr->gsr_interface) || 603 __put_user(interface, &kgsr->gsr_interface) ||
604 copy_in_user(&kgsr->gsr_group, &gsr32->gsr_group, 604 copy_in_user(&kgsr->gsr_group, &gsr32->gsr_group,
605 sizeof(kgsr->gsr_group)) || 605 sizeof(kgsr->gsr_group)) ||
606 copy_in_user(&kgsr->gsr_source, &gsr32->gsr_source, 606 copy_in_user(&kgsr->gsr_source, &gsr32->gsr_source,
607 sizeof(kgsr->gsr_source))) 607 sizeof(kgsr->gsr_source)))
608 return -EFAULT; 608 return -EFAULT;
609 koptval = (char __user *)kgsr; 609 koptval = (char __user *)kgsr;
610 koptlen = sizeof(struct group_source_req); 610 koptlen = sizeof(struct group_source_req);
611 break; 611 break;
612 } 612 }
613 case MCAST_MSFILTER: 613 case MCAST_MSFILTER:
614 { 614 {
615 struct compat_group_filter __user *gf32 = (void *)optval; 615 struct compat_group_filter __user *gf32 = (void *)optval;
616 struct group_filter __user *kgf; 616 struct group_filter __user *kgf;
617 u32 interface, fmode, numsrc; 617 u32 interface, fmode, numsrc;
618 618
619 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) || 619 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
620 __get_user(interface, &gf32->gf_interface) || 620 __get_user(interface, &gf32->gf_interface) ||
621 __get_user(fmode, &gf32->gf_fmode) || 621 __get_user(fmode, &gf32->gf_fmode) ||
622 __get_user(numsrc, &gf32->gf_numsrc)) 622 __get_user(numsrc, &gf32->gf_numsrc))
623 return -EFAULT; 623 return -EFAULT;
624 koptlen = optlen + sizeof(struct group_filter) - 624 koptlen = optlen + sizeof(struct group_filter) -
625 sizeof(struct compat_group_filter); 625 sizeof(struct compat_group_filter);
626 if (koptlen < GROUP_FILTER_SIZE(numsrc)) 626 if (koptlen < GROUP_FILTER_SIZE(numsrc))
627 return -EINVAL; 627 return -EINVAL;
628 kgf = compat_alloc_user_space(koptlen); 628 kgf = compat_alloc_user_space(koptlen);
629 if (!access_ok(VERIFY_WRITE, kgf, koptlen) || 629 if (!access_ok(VERIFY_WRITE, kgf, koptlen) ||
630 __put_user(interface, &kgf->gf_interface) || 630 __put_user(interface, &kgf->gf_interface) ||
631 __put_user(fmode, &kgf->gf_fmode) || 631 __put_user(fmode, &kgf->gf_fmode) ||
632 __put_user(numsrc, &kgf->gf_numsrc) || 632 __put_user(numsrc, &kgf->gf_numsrc) ||
633 copy_in_user(&kgf->gf_group, &gf32->gf_group, 633 copy_in_user(&kgf->gf_group, &gf32->gf_group,
634 sizeof(kgf->gf_group)) || 634 sizeof(kgf->gf_group)) ||
635 (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist, 635 (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist,
636 numsrc * sizeof(kgf->gf_slist[0])))) 636 numsrc * sizeof(kgf->gf_slist[0]))))
637 return -EFAULT; 637 return -EFAULT;
638 koptval = (char __user *)kgf; 638 koptval = (char __user *)kgf;
639 break; 639 break;
640 } 640 }
641 641
642 default: 642 default:
643 break; 643 break;
644 } 644 }
645 return setsockopt(sock, level, optname, koptval, koptlen); 645 return setsockopt(sock, level, optname, koptval, koptlen);
646 } 646 }
647 EXPORT_SYMBOL(compat_mc_setsockopt); 647 EXPORT_SYMBOL(compat_mc_setsockopt);
648 648
649 int compat_mc_getsockopt(struct sock *sock, int level, int optname, 649 int compat_mc_getsockopt(struct sock *sock, int level, int optname,
650 char __user *optval, int __user *optlen, 650 char __user *optval, int __user *optlen,
651 int (*getsockopt)(struct sock *, int, int, char __user *, int __user *)) 651 int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))
652 { 652 {
653 struct compat_group_filter __user *gf32 = (void *)optval; 653 struct compat_group_filter __user *gf32 = (void *)optval;
654 struct group_filter __user *kgf; 654 struct group_filter __user *kgf;
655 int __user *koptlen; 655 int __user *koptlen;
656 u32 interface, fmode, numsrc; 656 u32 interface, fmode, numsrc;
657 int klen, ulen, err; 657 int klen, ulen, err;
658 658
659 if (optname != MCAST_MSFILTER) 659 if (optname != MCAST_MSFILTER)
660 return getsockopt(sock, level, optname, optval, optlen); 660 return getsockopt(sock, level, optname, optval, optlen);
661 661
662 koptlen = compat_alloc_user_space(sizeof(*koptlen)); 662 koptlen = compat_alloc_user_space(sizeof(*koptlen));
663 if (!access_ok(VERIFY_READ, optlen, sizeof(*optlen)) || 663 if (!access_ok(VERIFY_READ, optlen, sizeof(*optlen)) ||
664 __get_user(ulen, optlen)) 664 __get_user(ulen, optlen))
665 return -EFAULT; 665 return -EFAULT;
666 666
667 /* adjust len for pad */ 667 /* adjust len for pad */
668 klen = ulen + sizeof(*kgf) - sizeof(*gf32); 668 klen = ulen + sizeof(*kgf) - sizeof(*gf32);
669 669
670 if (klen < GROUP_FILTER_SIZE(0)) 670 if (klen < GROUP_FILTER_SIZE(0))
671 return -EINVAL; 671 return -EINVAL;
672 672
673 if (!access_ok(VERIFY_WRITE, koptlen, sizeof(*koptlen)) || 673 if (!access_ok(VERIFY_WRITE, koptlen, sizeof(*koptlen)) ||
674 __put_user(klen, koptlen)) 674 __put_user(klen, koptlen))
675 return -EFAULT; 675 return -EFAULT;
676 676
677 /* have to allow space for previous compat_alloc_user_space, too */ 677 /* have to allow space for previous compat_alloc_user_space, too */
678 kgf = compat_alloc_user_space(klen+sizeof(*optlen)); 678 kgf = compat_alloc_user_space(klen+sizeof(*optlen));
679 679
680 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) || 680 if (!access_ok(VERIFY_READ, gf32, __COMPAT_GF0_SIZE) ||
681 __get_user(interface, &gf32->gf_interface) || 681 __get_user(interface, &gf32->gf_interface) ||
682 __get_user(fmode, &gf32->gf_fmode) || 682 __get_user(fmode, &gf32->gf_fmode) ||
683 __get_user(numsrc, &gf32->gf_numsrc) || 683 __get_user(numsrc, &gf32->gf_numsrc) ||
684 __put_user(interface, &kgf->gf_interface) || 684 __put_user(interface, &kgf->gf_interface) ||
685 __put_user(fmode, &kgf->gf_fmode) || 685 __put_user(fmode, &kgf->gf_fmode) ||
686 __put_user(numsrc, &kgf->gf_numsrc) || 686 __put_user(numsrc, &kgf->gf_numsrc) ||
687 copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group))) 687 copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group)))
688 return -EFAULT; 688 return -EFAULT;
689 689
690 err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen); 690 err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen);
691 if (err) 691 if (err)
692 return err; 692 return err;
693 693
694 if (!access_ok(VERIFY_READ, koptlen, sizeof(*koptlen)) || 694 if (!access_ok(VERIFY_READ, koptlen, sizeof(*koptlen)) ||
695 __get_user(klen, koptlen)) 695 __get_user(klen, koptlen))
696 return -EFAULT; 696 return -EFAULT;
697 697
698 ulen = klen - (sizeof(*kgf)-sizeof(*gf32)); 698 ulen = klen - (sizeof(*kgf)-sizeof(*gf32));
699 699
700 if (!access_ok(VERIFY_WRITE, optlen, sizeof(*optlen)) || 700 if (!access_ok(VERIFY_WRITE, optlen, sizeof(*optlen)) ||
701 __put_user(ulen, optlen)) 701 __put_user(ulen, optlen))
702 return -EFAULT; 702 return -EFAULT;
703 703
704 if (!access_ok(VERIFY_READ, kgf, klen) || 704 if (!access_ok(VERIFY_READ, kgf, klen) ||
705 !access_ok(VERIFY_WRITE, gf32, ulen) || 705 !access_ok(VERIFY_WRITE, gf32, ulen) ||
706 __get_user(interface, &kgf->gf_interface) || 706 __get_user(interface, &kgf->gf_interface) ||
707 __get_user(fmode, &kgf->gf_fmode) || 707 __get_user(fmode, &kgf->gf_fmode) ||
708 __get_user(numsrc, &kgf->gf_numsrc) || 708 __get_user(numsrc, &kgf->gf_numsrc) ||
709 __put_user(interface, &gf32->gf_interface) || 709 __put_user(interface, &gf32->gf_interface) ||
710 __put_user(fmode, &gf32->gf_fmode) || 710 __put_user(fmode, &gf32->gf_fmode) ||
711 __put_user(numsrc, &gf32->gf_numsrc)) 711 __put_user(numsrc, &gf32->gf_numsrc))
712 return -EFAULT; 712 return -EFAULT;
713 if (numsrc) { 713 if (numsrc) {
714 int copylen; 714 int copylen;
715 715
716 klen -= GROUP_FILTER_SIZE(0); 716 klen -= GROUP_FILTER_SIZE(0);
717 copylen = numsrc * sizeof(gf32->gf_slist[0]); 717 copylen = numsrc * sizeof(gf32->gf_slist[0]);
718 if (copylen > klen) 718 if (copylen > klen)
719 copylen = klen; 719 copylen = klen;
720 if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen)) 720 if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen))
721 return -EFAULT; 721 return -EFAULT;
722 } 722 }
723 return err; 723 return err;
724 } 724 }
725 EXPORT_SYMBOL(compat_mc_getsockopt); 725 EXPORT_SYMBOL(compat_mc_getsockopt);
726 726
727 727
728 /* Argument list sizes for compat_sys_socketcall */ 728 /* Argument list sizes for compat_sys_socketcall */
729 #define AL(x) ((x) * sizeof(u32)) 729 #define AL(x) ((x) * sizeof(u32))
730 static unsigned char nas[21] = { 730 static unsigned char nas[21] = {
731 AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), 731 AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
732 AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), 732 AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
733 AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), 733 AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
734 AL(4), AL(5), AL(4) 734 AL(4), AL(5), AL(4)
735 }; 735 };
736 #undef AL 736 #undef AL
737 737
738 COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) 738 COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags)
739 { 739 {
740 if (flags & MSG_CMSG_COMPAT) 740 if (flags & MSG_CMSG_COMPAT)
741 return -EINVAL; 741 return -EINVAL;
742 return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 742 return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
743 } 743 }
744 744
745 COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, 745 COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
746 unsigned int, vlen, unsigned int, flags) 746 unsigned int, vlen, unsigned int, flags)
747 { 747 {
748 if (flags & MSG_CMSG_COMPAT) 748 if (flags & MSG_CMSG_COMPAT)
749 return -EINVAL; 749 return -EINVAL;
750 return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 750 return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
751 flags | MSG_CMSG_COMPAT); 751 flags | MSG_CMSG_COMPAT);
752 } 752 }
753 753
754 COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) 754 COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags)
755 { 755 {
756 if (flags & MSG_CMSG_COMPAT) 756 if (flags & MSG_CMSG_COMPAT)
757 return -EINVAL; 757 return -EINVAL;
758 return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 758 return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
759 } 759 }
760 760
761 asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) 761 COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
762 { 762 {
763 return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT); 763 return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT);
764 } 764 }
765 765
766 asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len, 766 COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len,
767 unsigned int flags, struct sockaddr __user *addr, 767 unsigned int, flags, struct sockaddr __user *, addr,
768 int __user *addrlen) 768 int __user *, addrlen)
769 { 769 {
770 return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen); 770 return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen);
771 } 771 }
772 772
773 COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, 773 COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
774 unsigned int, vlen, unsigned int, flags, 774 unsigned int, vlen, unsigned int, flags,
775 struct compat_timespec __user *, timeout) 775 struct compat_timespec __user *, timeout)
776 { 776 {
777 int datagrams; 777 int datagrams;
778 struct timespec ktspec; 778 struct timespec ktspec;
779 779
780 if (flags & MSG_CMSG_COMPAT) 780 if (flags & MSG_CMSG_COMPAT)
781 return -EINVAL; 781 return -EINVAL;
782 782
783 if (timeout == NULL) 783 if (timeout == NULL)
784 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 784 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
785 flags | MSG_CMSG_COMPAT, NULL); 785 flags | MSG_CMSG_COMPAT, NULL);
786 786
787 if (compat_get_timespec(&ktspec, timeout)) 787 if (compat_get_timespec(&ktspec, timeout))
788 return -EFAULT; 788 return -EFAULT;
789 789
790 datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 790 datagrams = __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
791 flags | MSG_CMSG_COMPAT, &ktspec); 791 flags | MSG_CMSG_COMPAT, &ktspec);
792 if (datagrams > 0 && compat_put_timespec(&ktspec, timeout)) 792 if (datagrams > 0 && compat_put_timespec(&ktspec, timeout))
793 datagrams = -EFAULT; 793 datagrams = -EFAULT;
794 794
795 return datagrams; 795 return datagrams;
796 } 796 }
797 797
798 COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) 798 COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
799 { 799 {
800 int ret; 800 int ret;
801 u32 a[6]; 801 u32 a[6];
802 u32 a0, a1; 802 u32 a0, a1;
803 803
804 if (call < SYS_SOCKET || call > SYS_SENDMMSG) 804 if (call < SYS_SOCKET || call > SYS_SENDMMSG)
805 return -EINVAL; 805 return -EINVAL;
806 if (copy_from_user(a, args, nas[call])) 806 if (copy_from_user(a, args, nas[call]))
807 return -EFAULT; 807 return -EFAULT;
808 a0 = a[0]; 808 a0 = a[0];
809 a1 = a[1]; 809 a1 = a[1];
810 810
811 switch (call) { 811 switch (call) {
812 case SYS_SOCKET: 812 case SYS_SOCKET:
813 ret = sys_socket(a0, a1, a[2]); 813 ret = sys_socket(a0, a1, a[2]);
814 break; 814 break;
815 case SYS_BIND: 815 case SYS_BIND:
816 ret = sys_bind(a0, compat_ptr(a1), a[2]); 816 ret = sys_bind(a0, compat_ptr(a1), a[2]);
817 break; 817 break;
818 case SYS_CONNECT: 818 case SYS_CONNECT:
819 ret = sys_connect(a0, compat_ptr(a1), a[2]); 819 ret = sys_connect(a0, compat_ptr(a1), a[2]);
820 break; 820 break;
821 case SYS_LISTEN: 821 case SYS_LISTEN:
822 ret = sys_listen(a0, a1); 822 ret = sys_listen(a0, a1);
823 break; 823 break;
824 case SYS_ACCEPT: 824 case SYS_ACCEPT:
825 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); 825 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0);
826 break; 826 break;
827 case SYS_GETSOCKNAME: 827 case SYS_GETSOCKNAME:
828 ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); 828 ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
829 break; 829 break;
830 case SYS_GETPEERNAME: 830 case SYS_GETPEERNAME:
831 ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); 831 ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
832 break; 832 break;
833 case SYS_SOCKETPAIR: 833 case SYS_SOCKETPAIR:
834 ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); 834 ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
835 break; 835 break;
836 case SYS_SEND: 836 case SYS_SEND:
837 ret = sys_send(a0, compat_ptr(a1), a[2], a[3]); 837 ret = sys_send(a0, compat_ptr(a1), a[2], a[3]);
838 break; 838 break;
839 case SYS_SENDTO: 839 case SYS_SENDTO:
840 ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]); 840 ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
841 break; 841 break;
842 case SYS_RECV: 842 case SYS_RECV:
843 ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]); 843 ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]);
844 break; 844 break;
845 case SYS_RECVFROM: 845 case SYS_RECVFROM:
846 ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], 846 ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
847 compat_ptr(a[4]), compat_ptr(a[5])); 847 compat_ptr(a[4]), compat_ptr(a[5]));
848 break; 848 break;
849 case SYS_SHUTDOWN: 849 case SYS_SHUTDOWN:
850 ret = sys_shutdown(a0, a1); 850 ret = sys_shutdown(a0, a1);
851 break; 851 break;
852 case SYS_SETSOCKOPT: 852 case SYS_SETSOCKOPT:
853 ret = compat_sys_setsockopt(a0, a1, a[2], 853 ret = compat_sys_setsockopt(a0, a1, a[2],
854 compat_ptr(a[3]), a[4]); 854 compat_ptr(a[3]), a[4]);
855 break; 855 break;
856 case SYS_GETSOCKOPT: 856 case SYS_GETSOCKOPT:
857 ret = compat_sys_getsockopt(a0, a1, a[2], 857 ret = compat_sys_getsockopt(a0, a1, a[2],
858 compat_ptr(a[3]), compat_ptr(a[4])); 858 compat_ptr(a[3]), compat_ptr(a[4]));
859 break; 859 break;
860 case SYS_SENDMSG: 860 case SYS_SENDMSG:
861 ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]); 861 ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
862 break; 862 break;
863 case SYS_SENDMMSG: 863 case SYS_SENDMMSG:
864 ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]); 864 ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
865 break; 865 break;
866 case SYS_RECVMSG: 866 case SYS_RECVMSG:
867 ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); 867 ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
868 break; 868 break;
869 case SYS_RECVMMSG: 869 case SYS_RECVMMSG:
870 ret = compat_sys_recvmmsg(a0, compat_ptr(a1), a[2], a[3], 870 ret = compat_sys_recvmmsg(a0, compat_ptr(a1), a[2], a[3],
871 compat_ptr(a[4])); 871 compat_ptr(a[4]));
872 break; 872 break;
873 case SYS_ACCEPT4: 873 case SYS_ACCEPT4:
874 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); 874 ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);
875 break; 875 break;
876 default: 876 default:
877 ret = -EINVAL; 877 ret = -EINVAL;
878 break; 878 break;
879 } 879 }
880 return ret; 880 return ret;
881 } 881 }
882 882