From: Alan Maguire Date: Wed, 14 Jun 2017 13:06:27 +0000 (+0100) Subject: DTrace: IP provider use-after-free for drop-out probe points X-Git-Tag: v4.1.12-105.0.20170622_2100~105^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=0acae1e00534802b6a019db33cdde6540473ea72;p=users%2Fjedix%2Flinux-maple.git DTrace: IP provider use-after-free for drop-out probe points KASan warnings showed a possible use-after-free for skbs in error handling codepath after netfilter hooks have run. Hooks may free the skb, so we should not derefence it at drop-out probe points after NF_HOOK(). Orabug: 26267376 Signed-off-by: Alan Maguire Reviewed-by: Girish Moodalbail --- diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3326ba9c04280..c0de7f623b1e4 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1473,15 +1473,14 @@ int ip_send_skb(struct net *net, struct sk_buff *skb) if (err > 0) err = net_xmit_errno(err); if (err) { - struct iphdr *iph = ip_hdr(skb); - IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); + /* skb may have been freed */ DTRACE_IP(drop__out, - struct sk_buff * : pktinfo_t *, skb, - struct sock * : csinfo_t *, skb->sk, - void_ip_t * : ipinfo_t *, iph, - struct net_device * : ifinfo_t *, skb->dev, - struct iphdr * : ipv4info_t *, iph, + struct sk_buff * : pktinfo_t *, NULL, + struct sock * : csinfo_t *, NULL, + void_ip_t * : ipinfo_t *, NULL, + struct net_device * : ifinfo_t *, NULL, + struct iphdr * : ipv4info_t *, NULL, struct ipv6hdr * : ipv6info_t *, NULL, char * : string, "packet too short"); } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4abbd63e6f8d3..c5320592b3af5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1800,13 +1800,14 @@ int ip6_send_skb(struct sk_buff *skb) if (err > 0) err = net_xmit_errno(err); if (err) { + /* skb may have been freed */ DTRACE_IP(drop__out, - struct sk_buff * : pktinfo_t *, skb, - struct sock * : csinfo_t *, skb->sk, - void_ip_t * : ipinfo_t *, ipv6_hdr(skb), - struct net_device * : ifinfo_t *, skb->dev, + struct sk_buff * : pktinfo_t *, NULL, + struct sock * : csinfo_t *, NULL, + void_ip_t * : ipinfo_t *, NULL, + struct net_device * : ifinfo_t *, NULL, struct iphdr * : ipv4info_t *, NULL, - struct ipv6hdr * : ipv6info_t *, ipv6_hdr(skb), + struct ipv6hdr * : ipv6info_t *, NULL, char * : string, "out of memory"); IP6_INC_STATS(net, rt->rt6i_idev, diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 63397220b675b..c7620faeb2dbf 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1666,13 +1666,14 @@ out: ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); } else { + /* skb may have been freed */ DTRACE_IP(drop__out, - struct sk_buff * : pktinfo_t *, skb, - struct sock * : csinfo_t *, skb ? skb->sk : NULL, - void_ip_t * : ipinfo_t *, skb ? ipv6_hdr(skb) : NULL, - struct net_device * : ifinfo_t *, skb ? skb->dev : NULL, + struct sk_buff * : pktinfo_t *, NULL, + struct sock * : csinfo_t *, NULL, + void_ip_t * : ipinfo_t *, NULL, + struct net_device * : ifinfo_t *, idev->dev, struct iphdr * : ipv4info_t *, NULL, - struct ipv6hdr * : ipv6info_t *, skb ? ipv6_hdr(skb) : NULL, + struct ipv6hdr * : ipv6info_t *, NULL, char * : string, "multicast send error"); IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); @@ -2054,13 +2055,14 @@ out: ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len); } else { + /* skb may have been freed */ DTRACE_IP(drop__out, - struct sk_buff * : pktinfo_t *, skb, - struct sock * : csinfo_t *, skb ? skb->sk : NULL, - void_ip_t * : ipinfo_t *, skb ? ipv6_hdr(skb) : NULL, - struct net_device * : ifinfo_t *, skb ? skb->dev : NULL, + struct sk_buff * : pktinfo_t *, NULL, + struct sock * : csinfo_t *, sk, + void_ip_t * : ipinfo_t *, NULL, + struct net_device * : ifinfo_t *, idev->dev, struct iphdr * : ipv4info_t *, NULL, - struct ipv6hdr * : ipv6info_t *, skb ? ipv6_hdr(skb) : NULL, + struct ipv6hdr * : ipv6info_t *, NULL, char * : string, "multicast send error"); IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);