Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / net / compat.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c.
4  *
5  * Copyright (C) 2000           VA Linux Co
6  * Copyright (C) 2000           Don Dugger <n0ano@valinux.com>
7  * Copyright (C) 1999           Arun Sharma <arun.sharma@intel.com>
8  * Copyright (C) 1997,1998      Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9  * Copyright (C) 1997           David S. Miller (davem@caip.rutgers.edu)
10  * Copyright (C) 2000           Hewlett-Packard Co.
11  * Copyright (C) 2000           David Mosberger-Tang <davidm@hpl.hp.com>
12  * Copyright (C) 2000,2001      Andi Kleen, SuSE Labs
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/gfp.h>
17 #include <linux/fs.h>
18 #include <linux/types.h>
19 #include <linux/file.h>
20 #include <linux/icmpv6.h>
21 #include <linux/socket.h>
22 #include <linux/syscalls.h>
23 #include <linux/filter.h>
24 #include <linux/compat.h>
25 #include <linux/security.h>
26 #include <linux/audit.h>
27 #include <linux/export.h>
28
29 #include <net/scm.h>
30 #include <net/sock.h>
31 #include <net/ip.h>
32 #include <net/ipv6.h>
33 #include <linux/uaccess.h>
34 #include <net/compat.h>
35
36 int get_compat_msghdr(struct msghdr *kmsg,
37                       struct compat_msghdr __user *umsg,
38                       struct sockaddr __user **save_addr,
39                       struct iovec **iov)
40 {
41         struct compat_msghdr msg;
42         ssize_t err;
43
44         if (copy_from_user(&msg, umsg, sizeof(*umsg)))
45                 return -EFAULT;
46
47         kmsg->msg_flags = msg.msg_flags;
48         kmsg->msg_namelen = msg.msg_namelen;
49
50         if (!msg.msg_name)
51                 kmsg->msg_namelen = 0;
52
53         if (kmsg->msg_namelen < 0)
54                 return -EINVAL;
55
56         if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
57                 kmsg->msg_namelen = sizeof(struct sockaddr_storage);
58
59         kmsg->msg_control = compat_ptr(msg.msg_control);
60         kmsg->msg_controllen = msg.msg_controllen;
61
62         if (save_addr)
63                 *save_addr = compat_ptr(msg.msg_name);
64
65         if (msg.msg_name && kmsg->msg_namelen) {
66                 if (!save_addr) {
67                         err = move_addr_to_kernel(compat_ptr(msg.msg_name),
68                                                   kmsg->msg_namelen,
69                                                   kmsg->msg_name);
70                         if (err < 0)
71                                 return err;
72                 }
73         } else {
74                 kmsg->msg_name = NULL;
75                 kmsg->msg_namelen = 0;
76         }
77
78         if (msg.msg_iovlen > UIO_MAXIOV)
79                 return -EMSGSIZE;
80
81         kmsg->msg_iocb = NULL;
82
83         return compat_import_iovec(save_addr ? READ : WRITE,
84                                    compat_ptr(msg.msg_iov), msg.msg_iovlen,
85                                    UIO_FASTIOV, iov, &kmsg->msg_iter);
86 }
87
88 /* Bleech... */
89 #define CMSG_COMPAT_ALIGN(len)  ALIGN((len), sizeof(s32))
90
91 #define CMSG_COMPAT_DATA(cmsg)                          \
92         ((void __user *)((char __user *)(cmsg) + sizeof(struct compat_cmsghdr)))
93 #define CMSG_COMPAT_SPACE(len)                          \
94         (sizeof(struct compat_cmsghdr) + CMSG_COMPAT_ALIGN(len))
95 #define CMSG_COMPAT_LEN(len)                            \
96         (sizeof(struct compat_cmsghdr) + (len))
97
98 #define CMSG_COMPAT_FIRSTHDR(msg)                       \
99         (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ?     \
100          (struct compat_cmsghdr __user *)((msg)->msg_control) :         \
101          (struct compat_cmsghdr __user *)NULL)
102
103 #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
104         ((ucmlen) >= sizeof(struct compat_cmsghdr) && \
105          (ucmlen) <= (unsigned long) \
106          ((mhdr)->msg_controllen - \
107           ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
108
109 static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
110                 struct compat_cmsghdr __user *cmsg, int cmsg_len)
111 {
112         char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
113         if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) >
114                         msg->msg_controllen)
115                 return NULL;
116         return (struct compat_cmsghdr __user *)ptr;
117 }
118
119 /* There is a lot of hair here because the alignment rules (and
120  * thus placement) of cmsg headers and length are different for
121  * 32-bit apps.  -DaveM
122  */
123 int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
124                                unsigned char *stackbuf, int stackbuf_size)
125 {
126         struct compat_cmsghdr __user *ucmsg;
127         struct cmsghdr *kcmsg, *kcmsg_base;
128         compat_size_t ucmlen;
129         __kernel_size_t kcmlen, tmp;
130         int err = -EFAULT;
131
132         BUILD_BUG_ON(sizeof(struct compat_cmsghdr) !=
133                      CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)));
134
135         kcmlen = 0;
136         kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
137         ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
138         while (ucmsg != NULL) {
139                 if (get_user(ucmlen, &ucmsg->cmsg_len))
140                         return -EFAULT;
141
142                 /* Catch bogons. */
143                 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
144                         return -EINVAL;
145
146                 tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
147                 tmp = CMSG_ALIGN(tmp);
148                 kcmlen += tmp;
149                 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
150         }
151         if (kcmlen == 0)
152                 return -EINVAL;
153
154         /* The kcmlen holds the 64-bit version of the control length.
155          * It may not be modified as we do not stick it into the kmsg
156          * until we have successfully copied over all of the data
157          * from the user.
158          */
159         if (kcmlen > stackbuf_size)
160                 kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
161         if (kcmsg == NULL)
162                 return -ENOBUFS;
163
164         /* Now copy them over neatly. */
165         memset(kcmsg, 0, kcmlen);
166         ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
167         while (ucmsg != NULL) {
168                 if (__get_user(ucmlen, &ucmsg->cmsg_len))
169                         goto Efault;
170                 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
171                         goto Einval;
172                 tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
173                 if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
174                         goto Einval;
175                 kcmsg->cmsg_len = tmp;
176                 tmp = CMSG_ALIGN(tmp);
177                 if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
178                     __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
179                     copy_from_user(CMSG_DATA(kcmsg),
180                                    CMSG_COMPAT_DATA(ucmsg),
181                                    (ucmlen - sizeof(*ucmsg))))
182                         goto Efault;
183
184                 /* Advance. */
185                 kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
186                 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
187         }
188
189         /*
190          * check the length of messages copied in is the same as the
191          * what we get from the first loop
192          */
193         if ((char *)kcmsg - (char *)kcmsg_base != kcmlen)
194                 goto Einval;
195
196         /* Ok, looks like we made it.  Hook it up and return success. */
197         kmsg->msg_control = kcmsg_base;
198         kmsg->msg_controllen = kcmlen;
199         return 0;
200
201 Einval:
202         err = -EINVAL;
203 Efault:
204         if (kcmsg_base != (struct cmsghdr *)stackbuf)
205                 sock_kfree_s(sk, kcmsg_base, kcmlen);
206         return err;
207 }
208
209 int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
210 {
211         struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
212         struct compat_cmsghdr cmhdr;
213         struct old_timeval32 ctv;
214         struct old_timespec32 cts[3];
215         int cmlen;
216
217         if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
218                 kmsg->msg_flags |= MSG_CTRUNC;
219                 return 0; /* XXX: return error? check spec. */
220         }
221
222         if (!COMPAT_USE_64BIT_TIME) {
223                 if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
224                         struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;
225                         ctv.tv_sec = tv->tv_sec;
226                         ctv.tv_usec = tv->tv_usec;
227                         data = &ctv;
228                         len = sizeof(ctv);
229                 }
230                 if (level == SOL_SOCKET &&
231                     (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) {
232                         int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;
233                         int i;
234                         struct timespec *ts = (struct timespec *)data;
235                         for (i = 0; i < count; i++) {
236                                 cts[i].tv_sec = ts[i].tv_sec;
237                                 cts[i].tv_nsec = ts[i].tv_nsec;
238                         }
239                         data = &cts;
240                         len = sizeof(cts[0]) * count;
241                 }
242         }
243
244         cmlen = CMSG_COMPAT_LEN(len);
245         if (kmsg->msg_controllen < cmlen) {
246                 kmsg->msg_flags |= MSG_CTRUNC;
247                 cmlen = kmsg->msg_controllen;
248         }
249         cmhdr.cmsg_level = level;
250         cmhdr.cmsg_type = type;
251         cmhdr.cmsg_len = cmlen;
252
253         if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
254                 return -EFAULT;
255         if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
256                 return -EFAULT;
257         cmlen = CMSG_COMPAT_SPACE(len);
258         if (kmsg->msg_controllen < cmlen)
259                 cmlen = kmsg->msg_controllen;
260         kmsg->msg_control += cmlen;
261         kmsg->msg_controllen -= cmlen;
262         return 0;
263 }
264
265 void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
266 {
267         struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
268         int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
269         int fdnum = scm->fp->count;
270         struct file **fp = scm->fp->fp;
271         int __user *cmfptr;
272         int err = 0, i;
273
274         if (fdnum < fdmax)
275                 fdmax = fdnum;
276
277         for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) {
278                 int new_fd;
279                 err = security_file_receive(fp[i]);
280                 if (err)
281                         break;
282                 err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags
283                                           ? O_CLOEXEC : 0);
284                 if (err < 0)
285                         break;
286                 new_fd = err;
287                 err = put_user(new_fd, cmfptr);
288                 if (err) {
289                         put_unused_fd(new_fd);
290                         break;
291                 }
292                 /* Bump the usage count and install the file. */
293                 fd_install(new_fd, get_file(fp[i]));
294         }
295
296         if (i > 0) {
297                 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
298                 err = put_user(SOL_SOCKET, &cm->cmsg_level);
299                 if (!err)
300                         err = put_user(SCM_RIGHTS, &cm->cmsg_type);
301                 if (!err)
302                         err = put_user(cmlen, &cm->cmsg_len);
303                 if (!err) {
304                         cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
305                         kmsg->msg_control += cmlen;
306                         kmsg->msg_controllen -= cmlen;
307                 }
308         }
309         if (i < fdnum)
310                 kmsg->msg_flags |= MSG_CTRUNC;
311
312         /*
313          * All of the files that fit in the message have had their
314          * usage counts incremented, so we just free the list.
315          */
316         __scm_destroy(scm);
317 }
318
319 /* allocate a 64-bit sock_fprog on the user stack for duration of syscall. */
320 struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval)
321 {
322         struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
323         struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
324         struct compat_sock_fprog f32;
325         struct sock_fprog f;
326
327         if (copy_from_user(&f32, fprog32, sizeof(*fprog32)))
328                 return NULL;
329         memset(&f, 0, sizeof(f));
330         f.len = f32.len;
331         f.filter = compat_ptr(f32.filter);
332         if (copy_to_user(kfprog, &f, sizeof(struct sock_fprog)))
333                 return NULL;
334
335         return kfprog;
336 }
337 EXPORT_SYMBOL_GPL(get_compat_bpf_fprog);
338
339 static int do_set_attach_filter(struct socket *sock, int level, int optname,
340                                 char __user *optval, unsigned int optlen)
341 {
342         struct sock_fprog __user *kfprog;
343
344         kfprog = get_compat_bpf_fprog(optval);
345         if (!kfprog)
346                 return -EFAULT;
347
348         return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
349                               sizeof(struct sock_fprog));
350 }
351
352 static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
353                                 char __user *optval, unsigned int optlen)
354 {
355         if (optname == SO_ATTACH_FILTER ||
356             optname == SO_ATTACH_REUSEPORT_CBPF)
357                 return do_set_attach_filter(sock, level, optname,
358                                             optval, optlen);
359         return sock_setsockopt(sock, level, optname, optval, optlen);
360 }
361
362 static int __compat_sys_setsockopt(int fd, int level, int optname,
363                                    char __user *optval, unsigned int optlen)
364 {
365         int err;
366         struct socket *sock;
367
368         if (optlen > INT_MAX)
369                 return -EINVAL;
370
371         sock = sockfd_lookup(fd, &err);
372         if (sock) {
373                 err = security_socket_setsockopt(sock, level, optname);
374                 if (err) {
375                         sockfd_put(sock);
376                         return err;
377                 }
378
379                 if (level == SOL_SOCKET)
380                         err = compat_sock_setsockopt(sock, level,
381                                         optname, optval, optlen);
382                 else if (sock->ops->compat_setsockopt)
383                         err = sock->ops->compat_setsockopt(sock, level,
384                                         optname, optval, optlen);
385                 else
386                         err = sock->ops->setsockopt(sock, level,
387                                         optname, optval, optlen);
388                 sockfd_put(sock);
389         }
390         return err;
391 }
392
393 COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
394                        char __user *, optval, unsigned int, optlen)
395 {
396         return __compat_sys_setsockopt(fd, level, optname, optval, optlen);
397 }
398
399 static int __compat_sys_getsockopt(int fd, int level, int optname,
400                                    char __user *optval,
401                                    int __user *optlen)
402 {
403         int err;
404         struct socket *sock = sockfd_lookup(fd, &err);
405
406         if (sock) {
407                 err = security_socket_getsockopt(sock, level, optname);
408                 if (err) {
409                         sockfd_put(sock);
410                         return err;
411                 }
412
413                 if (level == SOL_SOCKET)
414                         err = sock_getsockopt(sock, level,
415                                         optname, optval, optlen);
416                 else if (sock->ops->compat_getsockopt)
417                         err = sock->ops->compat_getsockopt(sock, level,
418                                         optname, optval, optlen);
419                 else
420                         err = sock->ops->getsockopt(sock, level,
421                                         optname, optval, optlen);
422                 sockfd_put(sock);
423         }
424         return err;
425 }
426
427 COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
428                        char __user *, optval, int __user *, optlen)
429 {
430         return __compat_sys_getsockopt(fd, level, optname, optval, optlen);
431 }
432
433 struct compat_group_req {
434         __u32                            gr_interface;
435         struct __kernel_sockaddr_storage gr_group
436                 __aligned(4);
437 } __packed;
438
439 struct compat_group_source_req {
440         __u32                            gsr_interface;
441         struct __kernel_sockaddr_storage gsr_group
442                 __aligned(4);
443         struct __kernel_sockaddr_storage gsr_source
444                 __aligned(4);
445 } __packed;
446
447 struct compat_group_filter {
448         __u32                            gf_interface;
449         struct __kernel_sockaddr_storage gf_group
450                 __aligned(4);
451         __u32                            gf_fmode;
452         __u32                            gf_numsrc;
453         struct __kernel_sockaddr_storage gf_slist[1]
454                 __aligned(4);
455 } __packed;
456
457 #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \
458                         sizeof(struct __kernel_sockaddr_storage))
459
460
461 int compat_mc_setsockopt(struct sock *sock, int level, int optname,
462         char __user *optval, unsigned int optlen,
463         int (*setsockopt)(struct sock *, int, int, char __user *, unsigned int))
464 {
465         char __user     *koptval = optval;
466         int             koptlen = optlen;
467
468         switch (optname) {
469         case MCAST_JOIN_GROUP:
470         case MCAST_LEAVE_GROUP:
471         {
472                 struct compat_group_req __user *gr32 = (void __user *)optval;
473                 struct group_req __user *kgr =
474                         compat_alloc_user_space(sizeof(struct group_req));
475                 u32 interface;
476
477                 if (!access_ok(gr32, sizeof(*gr32)) ||
478                     !access_ok(kgr, sizeof(struct group_req)) ||
479                     __get_user(interface, &gr32->gr_interface) ||
480                     __put_user(interface, &kgr->gr_interface) ||
481                     copy_in_user(&kgr->gr_group, &gr32->gr_group,
482                                 sizeof(kgr->gr_group)))
483                         return -EFAULT;
484                 koptval = (char __user *)kgr;
485                 koptlen = sizeof(struct group_req);
486                 break;
487         }
488         case MCAST_JOIN_SOURCE_GROUP:
489         case MCAST_LEAVE_SOURCE_GROUP:
490         case MCAST_BLOCK_SOURCE:
491         case MCAST_UNBLOCK_SOURCE:
492         {
493                 struct compat_group_source_req __user *gsr32 = (void __user *)optval;
494                 struct group_source_req __user *kgsr = compat_alloc_user_space(
495                         sizeof(struct group_source_req));
496                 u32 interface;
497
498                 if (!access_ok(gsr32, sizeof(*gsr32)) ||
499                     !access_ok(kgsr,
500                         sizeof(struct group_source_req)) ||
501                     __get_user(interface, &gsr32->gsr_interface) ||
502                     __put_user(interface, &kgsr->gsr_interface) ||
503                     copy_in_user(&kgsr->gsr_group, &gsr32->gsr_group,
504                                 sizeof(kgsr->gsr_group)) ||
505                     copy_in_user(&kgsr->gsr_source, &gsr32->gsr_source,
506                                 sizeof(kgsr->gsr_source)))
507                         return -EFAULT;
508                 koptval = (char __user *)kgsr;
509                 koptlen = sizeof(struct group_source_req);
510                 break;
511         }
512         case MCAST_MSFILTER:
513         {
514                 struct compat_group_filter __user *gf32 = (void __user *)optval;
515                 struct group_filter __user *kgf;
516                 u32 interface, fmode, numsrc;
517
518                 if (!access_ok(gf32, __COMPAT_GF0_SIZE) ||
519                     __get_user(interface, &gf32->gf_interface) ||
520                     __get_user(fmode, &gf32->gf_fmode) ||
521                     __get_user(numsrc, &gf32->gf_numsrc))
522                         return -EFAULT;
523                 koptlen = optlen + sizeof(struct group_filter) -
524                                 sizeof(struct compat_group_filter);
525                 if (koptlen < GROUP_FILTER_SIZE(numsrc))
526                         return -EINVAL;
527                 kgf = compat_alloc_user_space(koptlen);
528                 if (!access_ok(kgf, koptlen) ||
529                     __put_user(interface, &kgf->gf_interface) ||
530                     __put_user(fmode, &kgf->gf_fmode) ||
531                     __put_user(numsrc, &kgf->gf_numsrc) ||
532                     copy_in_user(&kgf->gf_group, &gf32->gf_group,
533                                 sizeof(kgf->gf_group)) ||
534                     (numsrc && copy_in_user(kgf->gf_slist, gf32->gf_slist,
535                                 numsrc * sizeof(kgf->gf_slist[0]))))
536                         return -EFAULT;
537                 koptval = (char __user *)kgf;
538                 break;
539         }
540
541         default:
542                 break;
543         }
544         return setsockopt(sock, level, optname, koptval, koptlen);
545 }
546 EXPORT_SYMBOL(compat_mc_setsockopt);
547
548 int compat_mc_getsockopt(struct sock *sock, int level, int optname,
549         char __user *optval, int __user *optlen,
550         int (*getsockopt)(struct sock *, int, int, char __user *, int __user *))
551 {
552         struct compat_group_filter __user *gf32 = (void __user *)optval;
553         struct group_filter __user *kgf;
554         int __user      *koptlen;
555         u32 interface, fmode, numsrc;
556         int klen, ulen, err;
557
558         if (optname != MCAST_MSFILTER)
559                 return getsockopt(sock, level, optname, optval, optlen);
560
561         koptlen = compat_alloc_user_space(sizeof(*koptlen));
562         if (!access_ok(optlen, sizeof(*optlen)) ||
563             __get_user(ulen, optlen))
564                 return -EFAULT;
565
566         /* adjust len for pad */
567         klen = ulen + sizeof(*kgf) - sizeof(*gf32);
568
569         if (klen < GROUP_FILTER_SIZE(0))
570                 return -EINVAL;
571
572         if (!access_ok(koptlen, sizeof(*koptlen)) ||
573             __put_user(klen, koptlen))
574                 return -EFAULT;
575
576         /* have to allow space for previous compat_alloc_user_space, too */
577         kgf = compat_alloc_user_space(klen+sizeof(*optlen));
578
579         if (!access_ok(gf32, __COMPAT_GF0_SIZE) ||
580             __get_user(interface, &gf32->gf_interface) ||
581             __get_user(fmode, &gf32->gf_fmode) ||
582             __get_user(numsrc, &gf32->gf_numsrc) ||
583             __put_user(interface, &kgf->gf_interface) ||
584             __put_user(fmode, &kgf->gf_fmode) ||
585             __put_user(numsrc, &kgf->gf_numsrc) ||
586             copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group)))
587                 return -EFAULT;
588
589         err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen);
590         if (err)
591                 return err;
592
593         if (!access_ok(koptlen, sizeof(*koptlen)) ||
594             __get_user(klen, koptlen))
595                 return -EFAULT;
596
597         ulen = klen - (sizeof(*kgf)-sizeof(*gf32));
598
599         if (!access_ok(optlen, sizeof(*optlen)) ||
600             __put_user(ulen, optlen))
601                 return -EFAULT;
602
603         if (!access_ok(kgf, klen) ||
604             !access_ok(gf32, ulen) ||
605             __get_user(interface, &kgf->gf_interface) ||
606             __get_user(fmode, &kgf->gf_fmode) ||
607             __get_user(numsrc, &kgf->gf_numsrc) ||
608             __put_user(interface, &gf32->gf_interface) ||
609             __put_user(fmode, &gf32->gf_fmode) ||
610             __put_user(numsrc, &gf32->gf_numsrc))
611                 return -EFAULT;
612         if (numsrc) {
613                 int copylen;
614
615                 klen -= GROUP_FILTER_SIZE(0);
616                 copylen = numsrc * sizeof(gf32->gf_slist[0]);
617                 if (copylen > klen)
618                         copylen = klen;
619                 if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen))
620                         return -EFAULT;
621         }
622         return err;
623 }
624 EXPORT_SYMBOL(compat_mc_getsockopt);
625
626
627 /* Argument list sizes for compat_sys_socketcall */
628 #define AL(x) ((x) * sizeof(u32))
629 static unsigned char nas[21] = {
630         AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
631         AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
632         AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
633         AL(4), AL(5), AL(4)
634 };
635 #undef AL
636
637 static inline long __compat_sys_sendmsg(int fd,
638                                         struct compat_msghdr __user *msg,
639                                         unsigned int flags)
640 {
641         return __sys_sendmsg(fd, (struct user_msghdr __user *)msg,
642                              flags | MSG_CMSG_COMPAT, false);
643 }
644
645 COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg,
646                        unsigned int, flags)
647 {
648         return __compat_sys_sendmsg(fd, msg, flags);
649 }
650
651 static inline long __compat_sys_sendmmsg(int fd,
652                                          struct compat_mmsghdr __user *mmsg,
653                                          unsigned int vlen, unsigned int flags)
654 {
655         return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
656                               flags | MSG_CMSG_COMPAT, false);
657 }
658
659 COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
660                        unsigned int, vlen, unsigned int, flags)
661 {
662         return __compat_sys_sendmmsg(fd, mmsg, vlen, flags);
663 }
664
665 static inline long __compat_sys_recvmsg(int fd,
666                                         struct compat_msghdr __user *msg,
667                                         unsigned int flags)
668 {
669         return __sys_recvmsg(fd, (struct user_msghdr __user *)msg,
670                              flags | MSG_CMSG_COMPAT, false);
671 }
672
673 COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg,
674                        unsigned int, flags)
675 {
676         return __compat_sys_recvmsg(fd, msg, flags);
677 }
678
679 static inline long __compat_sys_recvfrom(int fd, void __user *buf,
680                                          compat_size_t len, unsigned int flags,
681                                          struct sockaddr __user *addr,
682                                          int __user *addrlen)
683 {
684         return __sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr,
685                               addrlen);
686 }
687
688 COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
689 {
690         return __compat_sys_recvfrom(fd, buf, len, flags, NULL, NULL);
691 }
692
693 COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len,
694                        unsigned int, flags, struct sockaddr __user *, addr,
695                        int __user *, addrlen)
696 {
697         return __compat_sys_recvfrom(fd, buf, len, flags, addr, addrlen);
698 }
699
700 COMPAT_SYSCALL_DEFINE5(recvmmsg_time64, int, fd, struct compat_mmsghdr __user *, mmsg,
701                        unsigned int, vlen, unsigned int, flags,
702                        struct __kernel_timespec __user *, timeout)
703 {
704         return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
705                               flags | MSG_CMSG_COMPAT, timeout, NULL);
706 }
707
708 #ifdef CONFIG_COMPAT_32BIT_TIME
709 COMPAT_SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct compat_mmsghdr __user *, mmsg,
710                        unsigned int, vlen, unsigned int, flags,
711                        struct old_timespec32 __user *, timeout)
712 {
713         return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
714                               flags | MSG_CMSG_COMPAT, NULL, timeout);
715 }
716 #endif
717
718 COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
719 {
720         u32 a[AUDITSC_ARGS];
721         unsigned int len;
722         u32 a0, a1;
723         int ret;
724
725         if (call < SYS_SOCKET || call > SYS_SENDMMSG)
726                 return -EINVAL;
727         len = nas[call];
728         if (len > sizeof(a))
729                 return -EINVAL;
730
731         if (copy_from_user(a, args, len))
732                 return -EFAULT;
733
734         ret = audit_socketcall_compat(len / sizeof(a[0]), a);
735         if (ret)
736                 return ret;
737
738         a0 = a[0];
739         a1 = a[1];
740
741         switch (call) {
742         case SYS_SOCKET:
743                 ret = __sys_socket(a0, a1, a[2]);
744                 break;
745         case SYS_BIND:
746                 ret = __sys_bind(a0, compat_ptr(a1), a[2]);
747                 break;
748         case SYS_CONNECT:
749                 ret = __sys_connect(a0, compat_ptr(a1), a[2]);
750                 break;
751         case SYS_LISTEN:
752                 ret = __sys_listen(a0, a1);
753                 break;
754         case SYS_ACCEPT:
755                 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0);
756                 break;
757         case SYS_GETSOCKNAME:
758                 ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
759                 break;
760         case SYS_GETPEERNAME:
761                 ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
762                 break;
763         case SYS_SOCKETPAIR:
764                 ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
765                 break;
766         case SYS_SEND:
767                 ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], NULL, 0);
768                 break;
769         case SYS_SENDTO:
770                 ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3],
771                                    compat_ptr(a[4]), a[5]);
772                 break;
773         case SYS_RECV:
774                 ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
775                                             NULL, NULL);
776                 break;
777         case SYS_RECVFROM:
778                 ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
779                                             compat_ptr(a[4]),
780                                             compat_ptr(a[5]));
781                 break;
782         case SYS_SHUTDOWN:
783                 ret = __sys_shutdown(a0, a1);
784                 break;
785         case SYS_SETSOCKOPT:
786                 ret = __compat_sys_setsockopt(a0, a1, a[2],
787                                               compat_ptr(a[3]), a[4]);
788                 break;
789         case SYS_GETSOCKOPT:
790                 ret = __compat_sys_getsockopt(a0, a1, a[2],
791                                               compat_ptr(a[3]),
792                                               compat_ptr(a[4]));
793                 break;
794         case SYS_SENDMSG:
795                 ret = __compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
796                 break;
797         case SYS_SENDMMSG:
798                 ret = __compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
799                 break;
800         case SYS_RECVMSG:
801                 ret = __compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
802                 break;
803         case SYS_RECVMMSG:
804                 ret = __sys_recvmmsg(a0, compat_ptr(a1), a[2],
805                                      a[3] | MSG_CMSG_COMPAT, NULL,
806                                      compat_ptr(a[4]));
807                 break;
808         case SYS_ACCEPT4:
809                 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);
810                 break;
811         default:
812                 ret = -EINVAL;
813                 break;
814         }
815         return ret;
816 }