OSDN Git Service

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[uclinux-h8/linux.git] / net / compat.c
index 94d3d5e..5cfd26a 100644 (file)
 #include <asm/uaccess.h>
 #include <net/compat.h>
 
-ssize_t get_compat_msghdr(struct msghdr *kmsg,
-                         struct compat_msghdr __user *umsg,
-                         struct sockaddr __user **save_addr,
-                         struct iovec **iov)
+int get_compat_msghdr(struct msghdr *kmsg,
+                     struct compat_msghdr __user *umsg,
+                     struct sockaddr __user **save_addr,
+                     struct iovec **iov)
 {
        compat_uptr_t uaddr, uiov, tmp3;
        compat_size_t nr_segs;
@@ -49,6 +49,13 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
            __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
            __get_user(kmsg->msg_flags, &umsg->msg_flags))
                return -EFAULT;
+
+       if (!uaddr)
+               kmsg->msg_namelen = 0;
+
+       if (kmsg->msg_namelen < 0)
+               return -EINVAL;
+
        if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
                kmsg->msg_namelen = sizeof(struct sockaddr_storage);
        kmsg->msg_control = compat_ptr(tmp3);
@@ -72,13 +79,11 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
        if (nr_segs > UIO_MAXIOV)
                return -EMSGSIZE;
 
-       err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE,
-                                          compat_ptr(uiov), nr_segs,
-                                          UIO_FASTIOV, *iov, iov);
-       if (err >= 0)
-               iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
-                             *iov, nr_segs, err);
-       return err;
+       kmsg->msg_iocb = NULL;
+
+       return compat_import_iovec(save_addr ? READ : WRITE,
+                                  compat_ptr(uiov), nr_segs,
+                                  UIO_FASTIOV, iov, &kmsg->msg_iter);
 }
 
 /* Bleech... */
@@ -508,25 +513,25 @@ COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
 struct compat_group_req {
        __u32                            gr_interface;
        struct __kernel_sockaddr_storage gr_group
-               __attribute__ ((aligned(4)));
+               __aligned(4);
 } __packed;
 
 struct compat_group_source_req {
        __u32                            gsr_interface;
        struct __kernel_sockaddr_storage gsr_group
-               __attribute__ ((aligned(4)));
+               __aligned(4);
        struct __kernel_sockaddr_storage gsr_source
-               __attribute__ ((aligned(4)));
+               __aligned(4);
 } __packed;
 
 struct compat_group_filter {
        __u32                            gf_interface;
        struct __kernel_sockaddr_storage gf_group
-               __attribute__ ((aligned(4)));
+               __aligned(4);
        __u32                            gf_fmode;
        __u32                            gf_numsrc;
        struct __kernel_sockaddr_storage gf_slist[1]
-               __attribute__ ((aligned(4)));
+               __aligned(4);
 } __packed;
 
 #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \