net: abstract out normal and compat msghdr import
This splits it into two parts, one that imports the message, and one that imports the iovec. This allows a caller to only do the first part, and import the iovec manually afterwards. No functional changes in this patch. Acked-by: David Miller <davem@davemloft.net> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
4d954c258a
commit
0a384abfae
|
@ -391,6 +391,10 @@ extern int recvmsg_copy_msghdr(struct msghdr *msg,
|
|||
struct user_msghdr __user *umsg, unsigned flags,
|
||||
struct sockaddr __user **uaddr,
|
||||
struct iovec **iov);
|
||||
extern int __copy_msghdr_from_user(struct msghdr *kmsg,
|
||||
struct user_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr,
|
||||
struct iovec __user **uiov, size_t *nsegs);
|
||||
|
||||
/* helpers which do the actual work for syscalls */
|
||||
extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
|
||||
|
|
|
@ -38,6 +38,9 @@ struct compat_cmsghdr {
|
|||
#define compat_mmsghdr mmsghdr
|
||||
#endif /* defined(CONFIG_COMPAT) */
|
||||
|
||||
int __get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr, compat_uptr_t *ptr,
|
||||
compat_size_t *len);
|
||||
int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *,
|
||||
struct sockaddr __user **, struct iovec **);
|
||||
struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval);
|
||||
|
|
26
net/compat.c
26
net/compat.c
|
@ -33,10 +33,10 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <net/compat.h>
|
||||
|
||||
int get_compat_msghdr(struct msghdr *kmsg,
|
||||
int __get_compat_msghdr(struct msghdr *kmsg,
|
||||
struct compat_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr,
|
||||
struct iovec **iov)
|
||||
compat_uptr_t *ptr, compat_size_t *len)
|
||||
{
|
||||
struct compat_msghdr msg;
|
||||
ssize_t err;
|
||||
|
@ -79,10 +79,26 @@ int get_compat_msghdr(struct msghdr *kmsg,
|
|||
return -EMSGSIZE;
|
||||
|
||||
kmsg->msg_iocb = NULL;
|
||||
*ptr = msg.msg_iov;
|
||||
*len = msg.msg_iovlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = compat_import_iovec(save_addr ? READ : WRITE,
|
||||
compat_ptr(msg.msg_iov), msg.msg_iovlen,
|
||||
UIO_FASTIOV, iov, &kmsg->msg_iter);
|
||||
int get_compat_msghdr(struct msghdr *kmsg,
|
||||
struct compat_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr,
|
||||
struct iovec **iov)
|
||||
{
|
||||
compat_uptr_t ptr;
|
||||
compat_size_t len;
|
||||
ssize_t err;
|
||||
|
||||
err = __get_compat_msghdr(kmsg, umsg, save_addr, &ptr, &len);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = compat_import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr),
|
||||
len, UIO_FASTIOV, iov, &kmsg->msg_iter);
|
||||
return err < 0 ? err : 0;
|
||||
}
|
||||
|
||||
|
|
21
net/socket.c
21
net/socket.c
|
@ -2226,10 +2226,10 @@ struct used_address {
|
|||
unsigned int name_len;
|
||||
};
|
||||
|
||||
static int copy_msghdr_from_user(struct msghdr *kmsg,
|
||||
int __copy_msghdr_from_user(struct msghdr *kmsg,
|
||||
struct user_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr,
|
||||
struct iovec **iov)
|
||||
struct iovec __user **uiov, size_t *nsegs)
|
||||
{
|
||||
struct user_msghdr msg;
|
||||
ssize_t err;
|
||||
|
@ -2271,6 +2271,23 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
|
|||
return -EMSGSIZE;
|
||||
|
||||
kmsg->msg_iocb = NULL;
|
||||
*uiov = msg.msg_iov;
|
||||
*nsegs = msg.msg_iovlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_msghdr_from_user(struct msghdr *kmsg,
|
||||
struct user_msghdr __user *umsg,
|
||||
struct sockaddr __user **save_addr,
|
||||
struct iovec **iov)
|
||||
{
|
||||
struct user_msghdr msg;
|
||||
ssize_t err;
|
||||
|
||||
err = __copy_msghdr_from_user(kmsg, umsg, save_addr, &msg.msg_iov,
|
||||
&msg.msg_iovlen);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = import_iovec(save_addr ? READ : WRITE,
|
||||
msg.msg_iov, msg.msg_iovlen,
|
||||
|
|
Loading…
Reference in New Issue