diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-27 18:34:53 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-04 13:14:34 -0400 |
commit | f8f8a727eab1c5b78c3703a461565b042979cc79 (patch) | |
tree | 1614a24192411d84b48c2f383fe3339666fc92a4 /net/compat.c | |
parent | 5da028a8af38eced330332d5ae51c212e9e86242 (diff) | |
download | lwn-f8f8a727eab1c5b78c3703a461565b042979cc79.tar.gz lwn-f8f8a727eab1c5b78c3703a461565b042979cc79.zip |
get_compat_bpf_fprog(): don't copyin field-by-field
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'net/compat.c')
-rw-r--r-- | net/compat.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/net/compat.c b/net/compat.c index dba5e222a0e5..6ded6c821d7a 100644 --- a/net/compat.c +++ b/net/compat.c @@ -313,15 +313,15 @@ struct sock_fprog __user *get_compat_bpf_fprog(char __user *optval) { struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); - compat_uptr_t ptr; - u16 len; - - if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) || - !access_ok(VERIFY_WRITE, kfprog, sizeof(struct sock_fprog)) || - __get_user(len, &fprog32->len) || - __get_user(ptr, &fprog32->filter) || - __put_user(len, &kfprog->len) || - __put_user(compat_ptr(ptr), &kfprog->filter)) + struct compat_sock_fprog f32; + struct sock_fprog f; + + if (copy_from_user(&f32, fprog32, sizeof(*fprog32))) + return NULL; + memset(&f, 0, sizeof(f)); + f.len = f32.len; + f.filter = compat_ptr(f32.filter); + if (copy_to_user(kfprog, &f, sizeof(struct sock_fprog))) return NULL; return kfprog; |