Skip to content

Commit 2173bd0

Browse files
committed
Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull network field-by-field copy-in updates from Al Viro: "This part of the misc compat queue was held back for review from networking folks and since davem has jus ACKed those..." * 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: get_compat_bpf_fprog(): don't copyin field-by-field get_compat_msghdr(): get rid of field-by-field copyin copy_msghdr_from_user(): get rid of field-by-field copyin
2 parents 568d135 + f8f8a72 commit 2173bd0

File tree

2 files changed

+37
-43
lines changed

2 files changed

+37
-43
lines changed

net/compat.c

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,33 @@ int get_compat_msghdr(struct msghdr *kmsg,
3737
struct sockaddr __user **save_addr,
3838
struct iovec **iov)
3939
{
40-
compat_uptr_t uaddr, uiov, tmp3;
41-
compat_size_t nr_segs;
40+
struct compat_msghdr msg;
4241
ssize_t err;
4342

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))
43+
if (copy_from_user(&msg, umsg, sizeof(*umsg)))
5244
return -EFAULT;
5345

54-
if (!uaddr)
46+
kmsg->msg_flags = msg.msg_flags;
47+
kmsg->msg_namelen = msg.msg_namelen;
48+
49+
if (!msg.msg_name)
5550
kmsg->msg_namelen = 0;
5651

5752
if (kmsg->msg_namelen < 0)
5853
return -EINVAL;
5954

6055
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
6156
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
62-
kmsg->msg_control = compat_ptr(tmp3);
57+
58+
kmsg->msg_control = compat_ptr(msg.msg_control);
59+
kmsg->msg_controllen = msg.msg_controllen;
6360

6461
if (save_addr)
65-
*save_addr = compat_ptr(uaddr);
62+
*save_addr = compat_ptr(msg.msg_name);
6663

67-
if (uaddr && kmsg->msg_namelen) {
64+
if (msg.msg_name && kmsg->msg_namelen) {
6865
if (!save_addr) {
69-
err = move_addr_to_kernel(compat_ptr(uaddr),
66+
err = move_addr_to_kernel(compat_ptr(msg.msg_name),
7067
kmsg->msg_namelen,
7168
kmsg->msg_name);
7269
if (err < 0)
@@ -77,13 +74,13 @@ int get_compat_msghdr(struct msghdr *kmsg,
7774
kmsg->msg_namelen = 0;
7875
}
7976

80-
if (nr_segs > UIO_MAXIOV)
77+
if (msg.msg_iovlen > UIO_MAXIOV)
8178
return -EMSGSIZE;
8279

8380
kmsg->msg_iocb = NULL;
8481

8582
return compat_import_iovec(save_addr ? READ : WRITE,
86-
compat_ptr(uiov), nr_segs,
83+
compat_ptr(msg.msg_iov), msg.msg_iovlen,
8784
UIO_FASTIOV, iov, &kmsg->msg_iter);
8885
}
8986

@@ -316,15 +313,15 @@ struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval)
316313
{
317314
struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
318315
struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
319-
compat_uptr_t ptr;
320-
u16 len;
321-
322-
if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) ||
323-
!access_ok(VERIFY_WRITE, kfprog, sizeof(struct sock_fprog)) ||
324-
__get_user(len, &fprog32->len) ||
325-
__get_user(ptr, &fprog32->filter) ||
326-
__put_user(len, &kfprog->len) ||
327-
__put_user(compat_ptr(ptr), &kfprog->filter))
316+
struct compat_sock_fprog f32;
317+
struct sock_fprog f;
318+
319+
if (copy_from_user(&f32, fprog32, sizeof(*fprog32)))
320+
return NULL;
321+
memset(&f, 0, sizeof(f));
322+
f.len = f32.len;
323+
f.filter = compat_ptr(f32.filter);
324+
if (copy_to_user(kfprog, &f, sizeof(struct sock_fprog)))
328325
return NULL;
329326

330327
return kfprog;

net/socket.c

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,22 +1910,18 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
19101910
struct sockaddr __user **save_addr,
19111911
struct iovec **iov)
19121912
{
1913-
struct sockaddr __user *uaddr;
1914-
struct iovec __user *uiov;
1915-
size_t nr_segs;
1913+
struct user_msghdr msg;
19161914
ssize_t err;
19171915

1918-
if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
1919-
__get_user(uaddr, &umsg->msg_name) ||
1920-
__get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
1921-
__get_user(uiov, &umsg->msg_iov) ||
1922-
__get_user(nr_segs, &umsg->msg_iovlen) ||
1923-
__get_user(kmsg->msg_control, &umsg->msg_control) ||
1924-
__get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
1925-
__get_user(kmsg->msg_flags, &umsg->msg_flags))
1916+
if (copy_from_user(&msg, umsg, sizeof(*umsg)))
19261917
return -EFAULT;
19271918

1928-
if (!uaddr)
1919+
kmsg->msg_control = msg.msg_control;
1920+
kmsg->msg_controllen = msg.msg_controllen;
1921+
kmsg->msg_flags = msg.msg_flags;
1922+
1923+
kmsg->msg_namelen = msg.msg_namelen;
1924+
if (!msg.msg_name)
19291925
kmsg->msg_namelen = 0;
19301926

19311927
if (kmsg->msg_namelen < 0)
@@ -1935,11 +1931,11 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
19351931
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
19361932

19371933
if (save_addr)
1938-
*save_addr = uaddr;
1934+
*save_addr = msg.msg_name;
19391935

1940-
if (uaddr && kmsg->msg_namelen) {
1936+
if (msg.msg_name && kmsg->msg_namelen) {
19411937
if (!save_addr) {
1942-
err = move_addr_to_kernel(uaddr, kmsg->msg_namelen,
1938+
err = move_addr_to_kernel(msg.msg_name, kmsg->msg_namelen,
19431939
kmsg->msg_name);
19441940
if (err < 0)
19451941
return err;
@@ -1949,12 +1945,13 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
19491945
kmsg->msg_namelen = 0;
19501946
}
19511947

1952-
if (nr_segs > UIO_MAXIOV)
1948+
if (msg.msg_iovlen > UIO_MAXIOV)
19531949
return -EMSGSIZE;
19541950

19551951
kmsg->msg_iocb = NULL;
19561952

1957-
return import_iovec(save_addr ? READ : WRITE, uiov, nr_segs,
1953+
return import_iovec(save_addr ? READ : WRITE,
1954+
msg.msg_iov, msg.msg_iovlen,
19581955
UIO_FASTIOV, iov, &kmsg->msg_iter);
19591956
}
19601957

0 commit comments

Comments
 (0)