net: relax SO_TXTIME CAP_NET_ADMIN check
authorEric Dumazet <edumazet@google.com>
Thu, 7 May 2020 17:05:39 +0000 (10:05 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 May 2020 01:17:32 +0000 (18:17 -0700)
Now sch_fq has horizon feature, we want to allow QUIC/UDP applications
to use EDT model so that pacing can be offloaded to the kernel (sch_fq)
or the NIC.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/sock.c

index b714162213aeae98bfee24d8b457547fe7abab4f..fd85e651ce284b6987f0e8fae94f76ec2c432899 100644 (file)
@@ -1152,23 +1152,31 @@ set_rcvbuf:
                break;
 
        case SO_TXTIME:
-               if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
-                       ret = -EPERM;
-               } else if (optlen != sizeof(struct sock_txtime)) {
+               if (optlen != sizeof(struct sock_txtime)) {
                        ret = -EINVAL;
+                       break;
                } else if (copy_from_user(&sk_txtime, optval,
                           sizeof(struct sock_txtime))) {
                        ret = -EFAULT;
+                       break;
                } else if (sk_txtime.flags & ~SOF_TXTIME_FLAGS_MASK) {
                        ret = -EINVAL;
-               } else {
-                       sock_valbool_flag(sk, SOCK_TXTIME, true);
-                       sk->sk_clockid = sk_txtime.clockid;
-                       sk->sk_txtime_deadline_mode =
-                               !!(sk_txtime.flags & SOF_TXTIME_DEADLINE_MODE);
-                       sk->sk_txtime_report_errors =
-                               !!(sk_txtime.flags & SOF_TXTIME_REPORT_ERRORS);
+                       break;
+               }
+               /* CLOCK_MONOTONIC is only used by sch_fq, and this packet
+                * scheduler has enough safe guards.
+                */
+               if (sk_txtime.clockid != CLOCK_MONOTONIC &&
+                   !ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
+                       ret = -EPERM;
+                       break;
                }
+               sock_valbool_flag(sk, SOCK_TXTIME, true);
+               sk->sk_clockid = sk_txtime.clockid;
+               sk->sk_txtime_deadline_mode =
+                       !!(sk_txtime.flags & SOF_TXTIME_DEADLINE_MODE);
+               sk->sk_txtime_report_errors =
+                       !!(sk_txtime.flags & SOF_TXTIME_REPORT_ERRORS);
                break;
 
        case SO_BINDTOIFINDEX: