aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-12-20 11:00:27 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-21 16:14:01 -0500
commitf7e75ba1772bc712af0070655ffd8b09906993b5 (patch)
treeef32b318efe584f845f05eb7f65daca803abb6a1 /net/ipv4
parent412ed94744d16806fbec3bd250fd94e71cde5a1f (diff)
ip_gre: fix possible use after free
Once skb_realloc_headroom() is called, tiph might point to freed memory. Cache tiph->ttl value before the reallocation, to avoid unexpected behavior. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_gre.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 8fcf0ed76548..58cb627560dd 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -750,6 +750,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
750 int gre_hlen; 750 int gre_hlen;
751 __be32 dst; 751 __be32 dst;
752 int mtu; 752 int mtu;
753 u8 ttl;
753 754
754 if (skb->ip_summed == CHECKSUM_PARTIAL && 755 if (skb->ip_summed == CHECKSUM_PARTIAL &&
755 skb_checksum_help(skb)) 756 skb_checksum_help(skb))
@@ -815,6 +816,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
815 goto tx_error; 816 goto tx_error;
816 } 817 }
817 818
819 ttl = tiph->ttl;
818 tos = tiph->tos; 820 tos = tiph->tos;
819 if (tos == 1) { 821 if (tos == 1) {
820 tos = 0; 822 tos = 0;
@@ -907,6 +909,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
907 dev_kfree_skb(skb); 909 dev_kfree_skb(skb);
908 skb = new_skb; 910 skb = new_skb;
909 old_iph = ip_hdr(skb); 911 old_iph = ip_hdr(skb);
912 /* Warning : tiph value might point to freed memory */
910 } 913 }
911 914
912 skb_reset_transport_header(skb); 915 skb_reset_transport_header(skb);
@@ -930,8 +933,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
930 iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); 933 iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
931 iph->daddr = fl4.daddr; 934 iph->daddr = fl4.daddr;
932 iph->saddr = fl4.saddr; 935 iph->saddr = fl4.saddr;
936 iph->ttl = ttl;
933 937
934 if ((iph->ttl = tiph->ttl) == 0) { 938 if (ttl == 0) {
935 if (skb->protocol == htons(ETH_P_IP)) 939 if (skb->protocol == htons(ETH_P_IP))
936 iph->ttl = old_iph->ttl; 940 iph->ttl = old_iph->ttl;
937#if IS_ENABLED(CONFIG_IPV6) 941#if IS_ENABLED(CONFIG_IPV6)