LCOV - code coverage report
Current view: top level - net - compat.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 261 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 14 0.0 %

          Line data    Source code
       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           0 : int __get_compat_msghdr(struct msghdr *kmsg,
      37             :                         struct compat_msghdr __user *umsg,
      38             :                         struct sockaddr __user **save_addr,
      39             :                         compat_uptr_t *ptr, compat_size_t *len)
      40             : {
      41           0 :         struct compat_msghdr msg;
      42           0 :         ssize_t err;
      43             : 
      44           0 :         if (copy_from_user(&msg, umsg, sizeof(*umsg)))
      45             :                 return -EFAULT;
      46             : 
      47           0 :         kmsg->msg_flags = msg.msg_flags;
      48           0 :         kmsg->msg_namelen = msg.msg_namelen;
      49             : 
      50           0 :         if (!msg.msg_name)
      51           0 :                 kmsg->msg_namelen = 0;
      52             : 
      53           0 :         if (kmsg->msg_namelen < 0)
      54             :                 return -EINVAL;
      55             : 
      56           0 :         if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
      57           0 :                 kmsg->msg_namelen = sizeof(struct sockaddr_storage);
      58             : 
      59           0 :         kmsg->msg_control_is_user = true;
      60           0 :         kmsg->msg_control_user = compat_ptr(msg.msg_control);
      61           0 :         kmsg->msg_controllen = msg.msg_controllen;
      62             : 
      63           0 :         if (save_addr)
      64           0 :                 *save_addr = compat_ptr(msg.msg_name);
      65             : 
      66           0 :         if (msg.msg_name && kmsg->msg_namelen) {
      67           0 :                 if (!save_addr) {
      68           0 :                         err = move_addr_to_kernel(compat_ptr(msg.msg_name),
      69             :                                                   kmsg->msg_namelen,
      70           0 :                                                   kmsg->msg_name);
      71           0 :                         if (err < 0)
      72             :                                 return err;
      73             :                 }
      74             :         } else {
      75           0 :                 kmsg->msg_name = NULL;
      76           0 :                 kmsg->msg_namelen = 0;
      77             :         }
      78             : 
      79           0 :         if (msg.msg_iovlen > UIO_MAXIOV)
      80             :                 return -EMSGSIZE;
      81             : 
      82           0 :         kmsg->msg_iocb = NULL;
      83           0 :         *ptr = msg.msg_iov;
      84           0 :         *len = msg.msg_iovlen;
      85           0 :         return 0;
      86             : }
      87             : 
      88           0 : int get_compat_msghdr(struct msghdr *kmsg,
      89             :                       struct compat_msghdr __user *umsg,
      90             :                       struct sockaddr __user **save_addr,
      91             :                       struct iovec **iov)
      92             : {
      93           0 :         compat_uptr_t ptr;
      94           0 :         compat_size_t len;
      95           0 :         ssize_t err;
      96             : 
      97           0 :         err = __get_compat_msghdr(kmsg, umsg, save_addr, &ptr, &len);
      98           0 :         if (err)
      99             :                 return err;
     100             : 
     101           0 :         err = import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr), len,
     102             :                            UIO_FASTIOV, iov, &kmsg->msg_iter);
     103           0 :         return err < 0 ? err : 0;
     104             : }
     105             : 
     106             : /* Bleech... */
     107             : #define CMSG_COMPAT_ALIGN(len)  ALIGN((len), sizeof(s32))
     108             : 
     109             : #define CMSG_COMPAT_DATA(cmsg)                          \
     110             :         ((void __user *)((char __user *)(cmsg) + sizeof(struct compat_cmsghdr)))
     111             : #define CMSG_COMPAT_SPACE(len)                          \
     112             :         (sizeof(struct compat_cmsghdr) + CMSG_COMPAT_ALIGN(len))
     113             : #define CMSG_COMPAT_LEN(len)                            \
     114             :         (sizeof(struct compat_cmsghdr) + (len))
     115             : 
     116             : #define CMSG_COMPAT_FIRSTHDR(msg)                       \
     117             :         (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ?       \
     118             :          (struct compat_cmsghdr __user *)((msg)->msg_control) :              \
     119             :          (struct compat_cmsghdr __user *)NULL)
     120             : 
     121             : #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
     122             :         ((ucmlen) >= sizeof(struct compat_cmsghdr) && \
     123             :          (ucmlen) <= (unsigned long) \
     124             :          ((mhdr)->msg_controllen - \
     125             :           ((char __user *)(ucmsg) - (char __user *)(mhdr)->msg_control_user)))
     126             : 
     127           0 : static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
     128             :                 struct compat_cmsghdr __user *cmsg, int cmsg_len)
     129             : {
     130           0 :         char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
     131           0 :         if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) >
     132           0 :                         msg->msg_controllen)
     133           0 :                 return NULL;
     134             :         return (struct compat_cmsghdr __user *)ptr;
     135             : }
     136             : 
     137             : /* There is a lot of hair here because the alignment rules (and
     138             :  * thus placement) of cmsg headers and length are different for
     139             :  * 32-bit apps.  -DaveM
     140             :  */
     141           0 : int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
     142             :                                unsigned char *stackbuf, int stackbuf_size)
     143             : {
     144           0 :         struct compat_cmsghdr __user *ucmsg;
     145           0 :         struct cmsghdr *kcmsg, *kcmsg_base;
     146           0 :         compat_size_t ucmlen;
     147           0 :         __kernel_size_t kcmlen, tmp;
     148           0 :         int err = -EFAULT;
     149             : 
     150           0 :         BUILD_BUG_ON(sizeof(struct compat_cmsghdr) !=
     151             :                      CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)));
     152             : 
     153           0 :         kcmlen = 0;
     154           0 :         kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
     155           0 :         ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
     156           0 :         while (ucmsg != NULL) {
     157           0 :                 if (get_user(ucmlen, &ucmsg->cmsg_len))
     158             :                         return -EFAULT;
     159             : 
     160             :                 /* Catch bogons. */
     161           0 :                 if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
     162             :                         return -EINVAL;
     163             : 
     164           0 :                 tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
     165           0 :                 tmp = CMSG_ALIGN(tmp);
     166           0 :                 kcmlen += tmp;
     167           0 :                 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
     168             :         }
     169           0 :         if (kcmlen == 0)
     170             :                 return -EINVAL;
     171             : 
     172             :         /* The kcmlen holds the 64-bit version of the control length.
     173             :          * It may not be modified as we do not stick it into the kmsg
     174             :          * until we have successfully copied over all of the data
     175             :          * from the user.
     176             :          */
     177           0 :         if (kcmlen > stackbuf_size)
     178           0 :                 kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
     179           0 :         if (kcmsg == NULL)
     180             :                 return -ENOBUFS;
     181             : 
     182             :         /* Now copy them over neatly. */
     183           0 :         memset(kcmsg, 0, kcmlen);
     184           0 :         ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
     185           0 :         while (ucmsg != NULL) {
     186           0 :                 struct compat_cmsghdr cmsg;
     187           0 :                 if (copy_from_user(&cmsg, ucmsg, sizeof(cmsg)))
     188           0 :                         goto Efault;
     189           0 :                 if (!CMSG_COMPAT_OK(cmsg.cmsg_len, ucmsg, kmsg))
     190           0 :                         goto Einval;
     191           0 :                 tmp = ((cmsg.cmsg_len - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
     192           0 :                 if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
     193           0 :                         goto Einval;
     194           0 :                 kcmsg->cmsg_len = tmp;
     195           0 :                 kcmsg->cmsg_level = cmsg.cmsg_level;
     196           0 :                 kcmsg->cmsg_type = cmsg.cmsg_type;
     197           0 :                 tmp = CMSG_ALIGN(tmp);
     198           0 :                 if (copy_from_user(CMSG_DATA(kcmsg),
     199             :                                    CMSG_COMPAT_DATA(ucmsg),
     200           0 :                                    (cmsg.cmsg_len - sizeof(*ucmsg))))
     201           0 :                         goto Efault;
     202             : 
     203             :                 /* Advance. */
     204           0 :                 kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
     205           0 :                 ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, cmsg.cmsg_len);
     206             :         }
     207             : 
     208             :         /*
     209             :          * check the length of messages copied in is the same as the
     210             :          * what we get from the first loop
     211             :          */
     212           0 :         if ((char *)kcmsg - (char *)kcmsg_base != kcmlen)
     213           0 :                 goto Einval;
     214             : 
     215             :         /* Ok, looks like we made it.  Hook it up and return success. */
     216           0 :         kmsg->msg_control = kcmsg_base;
     217           0 :         kmsg->msg_controllen = kcmlen;
     218           0 :         return 0;
     219             : 
     220             : Einval:
     221             :         err = -EINVAL;
     222           0 : Efault:
     223           0 :         if (kcmsg_base != (struct cmsghdr *)stackbuf)
     224           0 :                 sock_kfree_s(sk, kcmsg_base, kcmlen);
     225             :         return err;
     226             : }
     227             : 
     228           0 : int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
     229             : {
     230           0 :         struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
     231           0 :         struct compat_cmsghdr cmhdr;
     232           0 :         struct old_timeval32 ctv;
     233           0 :         struct old_timespec32 cts[3];
     234           0 :         int cmlen;
     235             : 
     236           0 :         if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
     237           0 :                 kmsg->msg_flags |= MSG_CTRUNC;
     238           0 :                 return 0; /* XXX: return error? check spec. */
     239             :         }
     240             : 
     241           0 :         if (!COMPAT_USE_64BIT_TIME) {
     242           0 :                 if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
     243           0 :                         struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;
     244           0 :                         ctv.tv_sec = tv->tv_sec;
     245           0 :                         ctv.tv_usec = tv->tv_usec;
     246           0 :                         data = &ctv;
     247           0 :                         len = sizeof(ctv);
     248             :                 }
     249           0 :                 if (level == SOL_SOCKET &&
     250           0 :                     (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) {
     251           0 :                         int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;
     252           0 :                         int i;
     253           0 :                         struct __kernel_old_timespec *ts = data;
     254           0 :                         for (i = 0; i < count; i++) {
     255           0 :                                 cts[i].tv_sec = ts[i].tv_sec;
     256           0 :                                 cts[i].tv_nsec = ts[i].tv_nsec;
     257             :                         }
     258           0 :                         data = &cts;
     259           0 :                         len = sizeof(cts[0]) * count;
     260             :                 }
     261             :         }
     262             : 
     263           0 :         cmlen = CMSG_COMPAT_LEN(len);
     264           0 :         if (kmsg->msg_controllen < cmlen) {
     265           0 :                 kmsg->msg_flags |= MSG_CTRUNC;
     266           0 :                 cmlen = kmsg->msg_controllen;
     267             :         }
     268           0 :         cmhdr.cmsg_level = level;
     269           0 :         cmhdr.cmsg_type = type;
     270           0 :         cmhdr.cmsg_len = cmlen;
     271             : 
     272           0 :         if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
     273             :                 return -EFAULT;
     274           0 :         if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
     275             :                 return -EFAULT;
     276           0 :         cmlen = CMSG_COMPAT_SPACE(len);
     277           0 :         if (kmsg->msg_controllen < cmlen)
     278           0 :                 cmlen = kmsg->msg_controllen;
     279           0 :         kmsg->msg_control += cmlen;
     280           0 :         kmsg->msg_controllen -= cmlen;
     281           0 :         return 0;
     282             : }
     283             : 
     284           0 : static int scm_max_fds_compat(struct msghdr *msg)
     285             : {
     286           0 :         if (msg->msg_controllen <= sizeof(struct compat_cmsghdr))
     287             :                 return 0;
     288           0 :         return (msg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
     289             : }
     290             : 
     291           0 : void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm)
     292             : {
     293           0 :         struct compat_cmsghdr __user *cm =
     294             :                 (struct compat_cmsghdr __user *)msg->msg_control;
     295           0 :         unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0;
     296           0 :         int fdmax = min_t(int, scm_max_fds_compat(msg), scm->fp->count);
     297           0 :         int __user *cmsg_data = CMSG_COMPAT_DATA(cm);
     298           0 :         int err = 0, i;
     299             : 
     300           0 :         for (i = 0; i < fdmax; i++) {
     301           0 :                 err = receive_fd_user(scm->fp->fp[i], cmsg_data + i, o_flags);
     302           0 :                 if (err < 0)
     303             :                         break;
     304             :         }
     305             : 
     306           0 :         if (i > 0) {
     307           0 :                 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
     308             : 
     309           0 :                 err = put_user(SOL_SOCKET, &cm->cmsg_level);
     310           0 :                 if (!err)
     311           0 :                         err = put_user(SCM_RIGHTS, &cm->cmsg_type);
     312           0 :                 if (!err)
     313           0 :                         err = put_user(cmlen, &cm->cmsg_len);
     314           0 :                 if (!err) {
     315           0 :                         cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
     316           0 :                         if (msg->msg_controllen < cmlen)
     317           0 :                                 cmlen = msg->msg_controllen;
     318           0 :                         msg->msg_control += cmlen;
     319           0 :                         msg->msg_controllen -= cmlen;
     320             :                 }
     321             :         }
     322             : 
     323           0 :         if (i < scm->fp->count || (scm->fp->count && fdmax <= 0))
     324           0 :                 msg->msg_flags |= MSG_CTRUNC;
     325             : 
     326             :         /*
     327             :          * All of the files that fit in the message have had their usage counts
     328             :          * incremented, so we just free the list.
     329             :          */
     330           0 :         __scm_destroy(scm);
     331           0 : }
     332             : 
     333             : /* Argument list sizes for compat_sys_socketcall */
     334             : #define AL(x) ((x) * sizeof(u32))
     335             : static unsigned char nas[21] = {
     336             :         AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
     337             :         AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
     338             :         AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
     339             :         AL(4), AL(5), AL(4)
     340             : };
     341             : #undef AL
     342             : 
     343           0 : static inline long __compat_sys_sendmsg(int fd,
     344             :                                         struct compat_msghdr __user *msg,
     345             :                                         unsigned int flags)
     346             : {
     347           0 :         return __sys_sendmsg(fd, (struct user_msghdr __user *)msg,
     348             :                              flags | MSG_CMSG_COMPAT, false);
     349             : }
     350             : 
     351           0 : COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg,
     352             :                        unsigned int, flags)
     353             : {
     354           0 :         return __compat_sys_sendmsg(fd, msg, flags);
     355             : }
     356             : 
     357           0 : static inline long __compat_sys_sendmmsg(int fd,
     358             :                                          struct compat_mmsghdr __user *mmsg,
     359             :                                          unsigned int vlen, unsigned int flags)
     360             : {
     361           0 :         return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
     362             :                               flags | MSG_CMSG_COMPAT, false);
     363             : }
     364             : 
     365           0 : COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
     366             :                        unsigned int, vlen, unsigned int, flags)
     367             : {
     368           0 :         return __compat_sys_sendmmsg(fd, mmsg, vlen, flags);
     369             : }
     370             : 
     371           0 : static inline long __compat_sys_recvmsg(int fd,
     372             :                                         struct compat_msghdr __user *msg,
     373             :                                         unsigned int flags)
     374             : {
     375           0 :         return __sys_recvmsg(fd, (struct user_msghdr __user *)msg,
     376             :                              flags | MSG_CMSG_COMPAT, false);
     377             : }
     378             : 
     379           0 : COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg,
     380             :                        unsigned int, flags)
     381             : {
     382           0 :         return __compat_sys_recvmsg(fd, msg, flags);
     383             : }
     384             : 
     385           0 : static inline long __compat_sys_recvfrom(int fd, void __user *buf,
     386             :                                          compat_size_t len, unsigned int flags,
     387             :                                          struct sockaddr __user *addr,
     388             :                                          int __user *addrlen)
     389             : {
     390           0 :         return __sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr,
     391             :                               addrlen);
     392             : }
     393             : 
     394           0 : COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
     395             : {
     396           0 :         return __compat_sys_recvfrom(fd, buf, len, flags, NULL, NULL);
     397             : }
     398             : 
     399           0 : COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len,
     400             :                        unsigned int, flags, struct sockaddr __user *, addr,
     401             :                        int __user *, addrlen)
     402             : {
     403           0 :         return __compat_sys_recvfrom(fd, buf, len, flags, addr, addrlen);
     404             : }
     405             : 
     406           0 : COMPAT_SYSCALL_DEFINE5(recvmmsg_time64, int, fd, struct compat_mmsghdr __user *, mmsg,
     407             :                        unsigned int, vlen, unsigned int, flags,
     408             :                        struct __kernel_timespec __user *, timeout)
     409             : {
     410           0 :         return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
     411             :                               flags | MSG_CMSG_COMPAT, timeout, NULL);
     412             : }
     413             : 
     414             : #ifdef CONFIG_COMPAT_32BIT_TIME
     415             : COMPAT_SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct compat_mmsghdr __user *, mmsg,
     416             :                        unsigned int, vlen, unsigned int, flags,
     417             :                        struct old_timespec32 __user *, timeout)
     418             : {
     419             :         return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
     420             :                               flags | MSG_CMSG_COMPAT, NULL, timeout);
     421             : }
     422             : #endif
     423             : 
     424           0 : COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
     425             : {
     426           0 :         u32 a[AUDITSC_ARGS];
     427           0 :         unsigned int len;
     428           0 :         u32 a0, a1;
     429           0 :         int ret;
     430             : 
     431           0 :         if (call < SYS_SOCKET || call > SYS_SENDMMSG)
     432             :                 return -EINVAL;
     433           0 :         len = nas[call];
     434           0 :         if (len > sizeof(a))
     435             :                 return -EINVAL;
     436             : 
     437           0 :         if (copy_from_user(a, args, len))
     438             :                 return -EFAULT;
     439             : 
     440           0 :         ret = audit_socketcall_compat(len / sizeof(a[0]), a);
     441           0 :         if (ret)
     442             :                 return ret;
     443             : 
     444           0 :         a0 = a[0];
     445           0 :         a1 = a[1];
     446             : 
     447           0 :         switch (call) {
     448           0 :         case SYS_SOCKET:
     449           0 :                 ret = __sys_socket(a0, a1, a[2]);
     450           0 :                 break;
     451           0 :         case SYS_BIND:
     452           0 :                 ret = __sys_bind(a0, compat_ptr(a1), a[2]);
     453           0 :                 break;
     454           0 :         case SYS_CONNECT:
     455           0 :                 ret = __sys_connect(a0, compat_ptr(a1), a[2]);
     456           0 :                 break;
     457           0 :         case SYS_LISTEN:
     458           0 :                 ret = __sys_listen(a0, a1);
     459           0 :                 break;
     460           0 :         case SYS_ACCEPT:
     461           0 :                 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0);
     462           0 :                 break;
     463           0 :         case SYS_GETSOCKNAME:
     464           0 :                 ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
     465           0 :                 break;
     466           0 :         case SYS_GETPEERNAME:
     467           0 :                 ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
     468           0 :                 break;
     469           0 :         case SYS_SOCKETPAIR:
     470           0 :                 ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
     471           0 :                 break;
     472           0 :         case SYS_SEND:
     473           0 :                 ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], NULL, 0);
     474           0 :                 break;
     475           0 :         case SYS_SENDTO:
     476           0 :                 ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3],
     477           0 :                                    compat_ptr(a[4]), a[5]);
     478           0 :                 break;
     479           0 :         case SYS_RECV:
     480           0 :                 ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
     481             :                                             NULL, NULL);
     482           0 :                 break;
     483           0 :         case SYS_RECVFROM:
     484           0 :                 ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
     485           0 :                                             compat_ptr(a[4]),
     486           0 :                                             compat_ptr(a[5]));
     487           0 :                 break;
     488           0 :         case SYS_SHUTDOWN:
     489           0 :                 ret = __sys_shutdown(a0, a1);
     490           0 :                 break;
     491           0 :         case SYS_SETSOCKOPT:
     492           0 :                 ret = __sys_setsockopt(a0, a1, a[2], compat_ptr(a[3]), a[4]);
     493           0 :                 break;
     494           0 :         case SYS_GETSOCKOPT:
     495           0 :                 ret = __sys_getsockopt(a0, a1, a[2], compat_ptr(a[3]),
     496           0 :                                        compat_ptr(a[4]));
     497           0 :                 break;
     498           0 :         case SYS_SENDMSG:
     499           0 :                 ret = __compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
     500           0 :                 break;
     501           0 :         case SYS_SENDMMSG:
     502           0 :                 ret = __compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
     503           0 :                 break;
     504           0 :         case SYS_RECVMSG:
     505           0 :                 ret = __compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
     506           0 :                 break;
     507           0 :         case SYS_RECVMMSG:
     508           0 :                 ret = __sys_recvmmsg(a0, compat_ptr(a1), a[2],
     509           0 :                                      a[3] | MSG_CMSG_COMPAT, NULL,
     510           0 :                                      compat_ptr(a[4]));
     511           0 :                 break;
     512           0 :         case SYS_ACCEPT4:
     513           0 :                 ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);
     514           0 :                 break;
     515             :         default:
     516             :                 ret = -EINVAL;
     517             :                 break;
     518             :         }
     519           0 :         return ret;
     520             : }

Generated by: LCOV version 1.14