get_compat_msghdr(): get rid of field-by-field copyin

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 5da028a8 ffb07550

+14 -17
+14 -17
net/compat.c
··· 37 struct sockaddr __user **save_addr, 38 struct iovec **iov) 39 { 40 - compat_uptr_t uaddr, uiov, tmp3; 41 - compat_size_t nr_segs; 42 ssize_t err; 43 44 - if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || 45 - __get_user(uaddr, &umsg->msg_name) || 46 - __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || 47 - __get_user(uiov, &umsg->msg_iov) || 48 - __get_user(nr_segs, &umsg->msg_iovlen) || 49 - __get_user(tmp3, &umsg->msg_control) || 50 - __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || 51 - __get_user(kmsg->msg_flags, &umsg->msg_flags)) 52 return -EFAULT; 53 54 - if (!uaddr) 55 kmsg->msg_namelen = 0; 56 57 if (kmsg->msg_namelen < 0) ··· 54 55 if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) 56 kmsg->msg_namelen = sizeof(struct sockaddr_storage); 57 - kmsg->msg_control = compat_ptr(tmp3); 58 59 if (save_addr) 60 - *save_addr = compat_ptr(uaddr); 61 62 - if (uaddr && kmsg->msg_namelen) { 63 if (!save_addr) { 64 - err = move_addr_to_kernel(compat_ptr(uaddr), 65 kmsg->msg_namelen, 66 kmsg->msg_name); 67 if (err < 0) ··· 74 kmsg->msg_namelen = 0; 75 } 76 77 - if (nr_segs > UIO_MAXIOV) 78 return -EMSGSIZE; 79 80 kmsg->msg_iocb = NULL; 81 82 return compat_import_iovec(save_addr ? READ : WRITE, 83 - compat_ptr(uiov), nr_segs, 84 UIO_FASTIOV, iov, &kmsg->msg_iter); 85 } 86
··· 37 struct sockaddr __user **save_addr, 38 struct iovec **iov) 39 { 40 + struct compat_msghdr msg; 41 ssize_t err; 42 43 + if (copy_from_user(&msg, umsg, sizeof(*umsg))) 44 return -EFAULT; 45 46 + kmsg->msg_flags = msg.msg_flags; 47 + kmsg->msg_namelen = msg.msg_namelen; 48 + 49 + if (!msg.msg_name) 50 kmsg->msg_namelen = 0; 51 52 if (kmsg->msg_namelen < 0) ··· 59 60 if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) 61 kmsg->msg_namelen = sizeof(struct sockaddr_storage); 62 + 63 + kmsg->msg_control = compat_ptr(msg.msg_control); 64 + kmsg->msg_controllen = msg.msg_controllen; 65 66 if (save_addr) 67 + *save_addr = compat_ptr(msg.msg_name); 68 69 + if (msg.msg_name && kmsg->msg_namelen) { 70 if (!save_addr) { 71 + err = move_addr_to_kernel(compat_ptr(msg.msg_name), 72 kmsg->msg_namelen, 73 kmsg->msg_name); 74 if (err < 0) ··· 77 kmsg->msg_namelen = 0; 78 } 79 80 + if (msg.msg_iovlen > UIO_MAXIOV) 81 return -EMSGSIZE; 82 83 kmsg->msg_iocb = NULL; 84 85 return compat_import_iovec(save_addr ? READ : WRITE, 86 + compat_ptr(msg.msg_iov), msg.msg_iovlen, 87 UIO_FASTIOV, iov, &kmsg->msg_iter); 88 } 89