diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-07-15 10:38:54 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-07-15 10:38:54 +0200 |
commit | 07ccdcd34ac39ddecb8ccd00e5f03d76e9be8881 (patch) | |
tree | ffd8a0ffd6d803e5fa78c115a83b7dcd3c246d7c /net/compat.c | |
parent | 3c8fad9183ab7b3b3471fd2bb3d604104dd447cb (diff) | |
parent | fa3a9f5744a92c0d7856d4e326c8d920d1d31116 (diff) | |
download | linux-07ccdcd34ac39ddecb8ccd00e5f03d76e9be8881.tar.bz2 |
Merge branch 'linus' into x86/apic, to refresh the branch
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/compat.c')
-rw-r--r-- | net/compat.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/net/compat.c b/net/compat.c index 5cfd26a0006f..1cd2ec046164 100644 --- a/net/compat.c +++ b/net/compat.c @@ -309,8 +309,8 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) __scm_destroy(scm); } -static int do_set_attach_filter(struct socket *sock, int level, int optname, - char __user *optval, unsigned int optlen) +/* allocate a 64-bit sock_fprog on the user stack for duration of syscall. */ +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)); @@ -323,6 +323,19 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname, __get_user(ptr, &fprog32->filter) || __put_user(len, &kfprog->len) || __put_user(compat_ptr(ptr), &kfprog->filter)) + return NULL; + + return kfprog; +} +EXPORT_SYMBOL_GPL(get_compat_bpf_fprog); + +static int do_set_attach_filter(struct socket *sock, int level, int optname, + char __user *optval, unsigned int optlen) +{ + struct sock_fprog __user *kfprog; + + kfprog = get_compat_bpf_fprog(optval); + if (!kfprog) return -EFAULT; return sock_setsockopt(sock, level, optname, (char __user *)kfprog, @@ -354,7 +367,8 @@ static int do_set_sock_timeout(struct socket *sock, int level, static int compat_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { - if (optname == SO_ATTACH_FILTER) + if (optname == SO_ATTACH_FILTER || + optname == SO_ATTACH_REUSEPORT_CBPF) return do_set_attach_filter(sock, level, optname, optval, optlen); if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) |