net: simplify cBPF setsockopt compat handling

Add a helper that copies either a native or compat bpf_fprog from
userspace after verifying the length, and remove the compat setsockopt
handlers that now aren't required.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Christoph Hellwig
2020-07-17 08:23:13 +02:00
committed by David S. Miller
parent d8a9b38f83
commit 4d295e5461
6 changed files with 40 additions and 96 deletions
+1 -44
View File
@@ -335,49 +335,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
__scm_destroy(scm);
}
/* 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));
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;
}
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,
sizeof(struct sock_fprog));
}
static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
{
if (optname == SO_ATTACH_FILTER ||
optname == SO_ATTACH_REUSEPORT_CBPF)
return do_set_attach_filter(sock, level, optname,
optval, optlen);
return sock_setsockopt(sock, level, optname, optval, optlen);
}
static int __compat_sys_setsockopt(int fd, int level, int optname,
char __user *optval, unsigned int optlen)
{
@@ -396,7 +353,7 @@ static int __compat_sys_setsockopt(int fd, int level, int optname,
}
if (level == SOL_SOCKET)
err = compat_sock_setsockopt(sock, level,
err = sock_setsockopt(sock, level,
optname, optval, optlen);
else if (sock->ops->compat_setsockopt)
err = sock->ops->compat_setsockopt(sock, level,