mirror of https://gitee.com/openkylin/linux.git
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 user_msghdr __user *umsg, unsigned flags,
|
||||||
struct sockaddr __user **uaddr,
|
struct sockaddr __user **uaddr,
|
||||||
struct iovec **iov);
|
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 */
|
/* helpers which do the actual work for syscalls */
|
||||||
extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
|
extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct compat_cmsghdr {
|
||||||
#define compat_mmsghdr mmsghdr
|
#define compat_mmsghdr mmsghdr
|
||||||
#endif /* defined(CONFIG_COMPAT) */
|
#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 *,
|
int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *,
|
||||||
struct sockaddr __user **, struct iovec **);
|
struct sockaddr __user **, struct iovec **);
|
||||||
struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval);
|
struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval);
|
||||||
|
|
30
net/compat.c
30
net/compat.c
|
@ -33,10 +33,10 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <net/compat.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 compat_msghdr __user *umsg,
|
||||||
struct sockaddr __user **save_addr,
|
struct sockaddr __user **save_addr,
|
||||||
struct iovec **iov)
|
compat_uptr_t *ptr, compat_size_t *len)
|
||||||
{
|
{
|
||||||
struct compat_msghdr msg;
|
struct compat_msghdr msg;
|
||||||
ssize_t err;
|
ssize_t err;
|
||||||
|
@ -79,10 +79,26 @@ int get_compat_msghdr(struct msghdr *kmsg,
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
kmsg->msg_iocb = NULL;
|
kmsg->msg_iocb = NULL;
|
||||||
|
*ptr = msg.msg_iov;
|
||||||
|
*len = msg.msg_iovlen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
err = compat_import_iovec(save_addr ? READ : WRITE,
|
int get_compat_msghdr(struct msghdr *kmsg,
|
||||||
compat_ptr(msg.msg_iov), msg.msg_iovlen,
|
struct compat_msghdr __user *umsg,
|
||||||
UIO_FASTIOV, iov, &kmsg->msg_iter);
|
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;
|
return err < 0 ? err : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
net/socket.c
25
net/socket.c
|
@ -2226,10 +2226,10 @@ struct used_address {
|
||||||
unsigned int name_len;
|
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 user_msghdr __user *umsg,
|
||||||
struct sockaddr __user **save_addr,
|
struct sockaddr __user **save_addr,
|
||||||
struct iovec **iov)
|
struct iovec __user **uiov, size_t *nsegs)
|
||||||
{
|
{
|
||||||
struct user_msghdr msg;
|
struct user_msghdr msg;
|
||||||
ssize_t err;
|
ssize_t err;
|
||||||
|
@ -2271,6 +2271,23 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
|
|
||||||
kmsg->msg_iocb = NULL;
|
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,
|
err = import_iovec(save_addr ? READ : WRITE,
|
||||||
msg.msg_iov, msg.msg_iovlen,
|
msg.msg_iov, msg.msg_iovlen,
|
||||||
|
|
Loading…
Reference in New Issue