aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/net/ipv4/bpfilter/sockopt.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-07-23 08:09:08 +0200
committerDavid S. Miller <davem@davemloft.net>2020-07-24 15:41:54 -0700
commit6d04fe15f78acdf8e32329e208552e226f7a8ae6 (patch)
tree90ff9c419f8244651aa420349756cc371d539646 /net/ipv4/bpfilter/sockopt.c
parentnet: pass a sockptr_t into ->setsockopt (diff)
downloadwireguard-linux-6d04fe15f78acdf8e32329e208552e226f7a8ae6.tar.xz
wireguard-linux-6d04fe15f78acdf8e32329e208552e226f7a8ae6.zip
net: optimize the sockptr_t for unified kernel/user address spaces
For architectures like x86 and arm64 we don't need the separate bit to indicate that a pointer is a kernel pointer as the address spaces are unified. That way the sockptr_t can be reduced to a union of two pointers, which leads to nicer calling conventions. The only caveat is that we need to check that users don't pass in kernel address and thus gain access to kernel memory. Thus the USER_SOCKPTR helper is replaced with a init_user_sockptr function that does this check and returns an error if it fails. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/bpfilter/sockopt.c')
-rw-r--r--net/ipv4/bpfilter/sockopt.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/ipv4/bpfilter/sockopt.c b/net/ipv4/bpfilter/sockopt.c
index 1b34cb9a7708..94f18d2352d0 100644
--- a/net/ipv4/bpfilter/sockopt.c
+++ b/net/ipv4/bpfilter/sockopt.c
@@ -57,16 +57,18 @@ int bpfilter_ip_set_sockopt(struct sock *sk, int optname, sockptr_t optval,
return bpfilter_mbox_request(sk, optname, optval, optlen, true);
}
-int bpfilter_ip_get_sockopt(struct sock *sk, int optname, char __user *optval,
- int __user *optlen)
+int bpfilter_ip_get_sockopt(struct sock *sk, int optname,
+ char __user *user_optval, int __user *optlen)
{
- int len;
+ sockptr_t optval;
+ int err, len;
if (get_user(len, optlen))
return -EFAULT;
-
- return bpfilter_mbox_request(sk, optname, USER_SOCKPTR(optval), len,
- false);
+ err = init_user_sockptr(&optval, user_optval);
+ if (err)
+ return err;
+ return bpfilter_mbox_request(sk, optname, optval, len, false);
}
static int __init bpfilter_sockopt_init(void)