sock: Reset dst when changing sk_mark via setsockopt
authorDavid Barmann <david.barmann@stackpath.com>
Thu, 8 Nov 2018 14:13:35 +0000 (08:13 -0600)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Nov 2018 03:36:13 +0000 (19:36 -0800)
When setting the SO_MARK socket option, if the mark changes, the dst
needs to be reset so that a new route lookup is performed.

This fixes the case where an application wants to change routing by
setting a new sk_mark.  If this is done after some packets have already
been sent, the dst is cached and has no effect.

Signed-off-by: David Barmann <david.barmann@stackpath.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/sock.c

index 7b304e4..6d7e189 100644 (file)
@@ -952,10 +952,12 @@ set_rcvbuf:
                        clear_bit(SOCK_PASSSEC, &sock->flags);
                break;
        case SO_MARK:
-               if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
+               if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
                        ret = -EPERM;
-               else
+               } else if (val != sk->sk_mark) {
                        sk->sk_mark = val;
+                       sk_dst_reset(sk);
+               }
                break;
 
        case SO_RXQ_OVFL: