summaryrefslogtreecommitdiffstats
path: root/net/tls/tls_main.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2020-07-24 15:41:54 -0700
committerDavid S. Miller <davem@davemloft.net>2020-07-24 15:41:54 -0700
commit7c4c24168014f250241b6df66ca5bae37eda7ffc (patch)
tree90ff9c419f8244651aa420349756cc371d539646 /net/tls/tls_main.c
parent197569f72a1a3512ef294bae68d100d613f38f6a (diff)
parent6d04fe15f78acdf8e32329e208552e226f7a8ae6 (diff)
downloadlinux-7c4c24168014f250241b6df66ca5bae37eda7ffc.tar.bz2
Merge branch 'get-rid-of-the-address_space-override-in-setsockopt-v2'
Christoph Hellwig says: ==================== get rid of the address_space override in setsockopt v2 setsockopt is the last place in architecture-independ code that still uses set_fs to force the uaccess routines to operate on kernel pointers. This series adds a new sockptr_t type that can contained either a kernel or user pointer, and which has accessors that do the right thing, and then uses it for setsockopt, starting by refactoring some low-level helpers and moving them over to it before finally doing the main setsockopt method. Note that apparently the eBPF selftests do not even cover this path, so the series has been tested with a testing patch that always copies the data first and passes a kernel pointer. This is something that works for most common sockopts (and is something that the ePBF support relies on), but unfortunately in various corner cases we either don't use the passed in length, or in one case actually copy data back from setsockopt, or in case of bpfilter straight out do not work with kernel pointers at all. Against net-next/master. Changes since v1: - check that users don't pass in kernel addresses - more bpfilter cleanups - cosmetic mptcp tweak ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r--net/tls/tls_main.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index ec10041c6b7d..d77f7d821130 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -450,7 +450,7 @@ static int tls_getsockopt(struct sock *sk, int level, int optname,
return do_tls_getsockopt(sk, optname, optval, optlen);
}
-static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
+static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
unsigned int optlen, int tx)
{
struct tls_crypto_info *crypto_info;
@@ -460,7 +460,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
int rc = 0;
int conf;
- if (!optval || (optlen < sizeof(*crypto_info))) {
+ if (sockptr_is_null(optval) || (optlen < sizeof(*crypto_info))) {
rc = -EINVAL;
goto out;
}
@@ -479,7 +479,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
goto out;
}
- rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info));
+ rc = copy_from_sockptr(crypto_info, optval, sizeof(*crypto_info));
if (rc) {
rc = -EFAULT;
goto err_crypto_info;
@@ -522,8 +522,9 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
goto err_crypto_info;
}
- rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info),
- optlen - sizeof(*crypto_info));
+ sockptr_advance(optval, sizeof(*crypto_info));
+ rc = copy_from_sockptr(crypto_info + 1, optval,
+ optlen - sizeof(*crypto_info));
if (rc) {
rc = -EFAULT;
goto err_crypto_info;
@@ -579,8 +580,8 @@ out:
return rc;
}
-static int do_tls_setsockopt(struct sock *sk, int optname,
- char __user *optval, unsigned int optlen)
+static int do_tls_setsockopt(struct sock *sk, int optname, sockptr_t optval,
+ unsigned int optlen)
{
int rc = 0;
@@ -600,7 +601,7 @@ static int do_tls_setsockopt(struct sock *sk, int optname,
}
static int tls_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
+ sockptr_t optval, unsigned int optlen)
{
struct tls_context *ctx = tls_get_ctx(sk);