diff options
author | David S. Miller <davem@davemloft.net> | 2019-03-02 10:08:31 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-03-02 10:08:31 +0300 |
commit | 061ae26ff47f79fb2ce09b2577ebab32d4fe9fe1 (patch) | |
tree | ee7160784b8e3eca7187baa41bc586debd9c7143 | |
parent | 255c1c7279abf991113e7c9c29f91e9f1a5776a9 (diff) | |
parent | 677f136c6b88ac09a5b1c84dc4473e5901cf218b (diff) | |
download | linux-061ae26ff47f79fb2ce09b2577ebab32d4fe9fe1.tar.xz |
Merge branch 'SO_MAX_PACING_RATE-64-bit'
Eric Dumazet says:
====================
net: 64bit support for SO_MAX_PACING_RATE
64bit kernels adopted 64bit type for sk_max_pacing_rate in linux-4.20
We can change how we implement SO_MAX_PACING_RATE socket option
to support 64bit values to/from user space as well.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/sock.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index f5d82f3fa474..782343bb925b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1108,15 +1108,23 @@ set_rcvbuf: #endif case SO_MAX_PACING_RATE: - if (val != ~0U) + { + unsigned long ulval = (val == ~0U) ? ~0UL : val; + + if (sizeof(ulval) != sizeof(val) && + optlen >= sizeof(ulval) && + get_user(ulval, (unsigned long __user *)optval)) { + ret = -EFAULT; + break; + } + if (ulval != ~0UL) cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); - sk->sk_max_pacing_rate = (val == ~0U) ? ~0UL : val; - sk->sk_pacing_rate = min(sk->sk_pacing_rate, - sk->sk_max_pacing_rate); + sk->sk_max_pacing_rate = ulval; + sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval); break; - + } case SO_INCOMING_CPU: sk->sk_incoming_cpu = val; break; @@ -1211,6 +1219,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, union { int val; u64 val64; + unsigned long ulval; struct linger ling; struct old_timeval32 tm32; struct __kernel_old_timeval tm; @@ -1456,8 +1465,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname, #endif case SO_MAX_PACING_RATE: - /* 32bit version */ - v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); + if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) { + lv = sizeof(v.ulval); + v.ulval = sk->sk_max_pacing_rate; + } else { + /* 32bit version */ + v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); + } break; case SO_INCOMING_CPU: |