]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/ipv4/udp.c
udp: fix secpath leak
[karo-tx-linux.git] / net / ipv4 / udp.c
index a7c804f73990a0610bc85c02fc2dd76858973c22..62344804baaef96daf405dbdd5418db541b95864 100644 (file)
@@ -1176,7 +1176,7 @@ static void udp_set_dev_scratch(struct sk_buff *skb)
        scratch->csum_unnecessary = !!skb_csum_unnecessary(skb);
        scratch->is_linear = !skb_is_nonlinear(skb);
 #endif
-       if (likely(!skb->_skb_refdst))
+       if (likely(!skb->_skb_refdst && !skb_sec_path(skb)))
                scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
 }
 
@@ -1574,7 +1574,8 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
                return ip_recv_error(sk, msg, len, addr_len);
 
 try_again:
-       peeking = off = sk_peek_offset(sk, flags);
+       peeking = flags & MSG_PEEK;
+       off = sk_peek_offset(sk, flags);
        skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
        if (!skb)
                return err;
@@ -1928,14 +1929,16 @@ drop:
 /* For TCP sockets, sk_rx_dst is protected by socket lock
  * For UDP, we use xchg() to guard against concurrent changes.
  */
-void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
+bool udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
 {
        struct dst_entry *old;
 
        if (dst_hold_safe(dst)) {
                old = xchg(&sk->sk_rx_dst, dst);
                dst_release(old);
+               return old != dst;
        }
+       return false;
 }
 EXPORT_SYMBOL(udp_sk_rx_dst_set);