OSDN Git Service

switch cmsghdr_from_user_compat_to_kern() to copy_from_user()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 31 May 2020 01:06:55 +0000 (02:06 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 1 Jun 2020 19:05:45 +0000 (12:05 -0700)
no point getting compat_cmsghdr field-by-field

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/compat.c

index afd7b44..5e3041a 100644 (file)
@@ -183,20 +183,21 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
        memset(kcmsg, 0, kcmlen);
        ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
        while (ucmsg != NULL) {
-               if (__get_user(ucmlen, &ucmsg->cmsg_len))
+               struct compat_cmsghdr cmsg;
+               if (copy_from_user(&cmsg, ucmsg, sizeof(cmsg)))
                        goto Efault;
-               if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
+               if (!CMSG_COMPAT_OK(cmsg.cmsg_len, ucmsg, kmsg))
                        goto Einval;
-               tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
+               tmp = ((cmsg.cmsg_len - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
                if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
                        goto Einval;
                kcmsg->cmsg_len = tmp;
+               kcmsg->cmsg_level = cmsg.cmsg_level;
+               kcmsg->cmsg_type = cmsg.cmsg_type;
                tmp = CMSG_ALIGN(tmp);
-               if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
-                   __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
-                   copy_from_user(CMSG_DATA(kcmsg),
+               if (copy_from_user(CMSG_DATA(kcmsg),
                                   CMSG_COMPAT_DATA(ucmsg),
-                                  (ucmlen - sizeof(*ucmsg))))
+                                  (cmsg.cmsg_len - sizeof(*ucmsg))))
                        goto Efault;
 
                /* Advance. */