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>
This commit is contained in:
Родитель
412ed94744
Коммит
f7e75ba177
|
@ -750,6 +750,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
int gre_hlen;
|
int gre_hlen;
|
||||||
__be32 dst;
|
__be32 dst;
|
||||||
int mtu;
|
int mtu;
|
||||||
|
u8 ttl;
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||||
skb_checksum_help(skb))
|
skb_checksum_help(skb))
|
||||||
|
@ -815,6 +816,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
goto tx_error;
|
goto tx_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ttl = tiph->ttl;
|
||||||
tos = tiph->tos;
|
tos = tiph->tos;
|
||||||
if (tos == 1) {
|
if (tos == 1) {
|
||||||
tos = 0;
|
tos = 0;
|
||||||
|
@ -907,6 +909,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
skb = new_skb;
|
skb = new_skb;
|
||||||
old_iph = ip_hdr(skb);
|
old_iph = ip_hdr(skb);
|
||||||
|
/* Warning : tiph value might point to freed memory */
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
|
@ -930,8 +933,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
|
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
|
||||||
iph->daddr = fl4.daddr;
|
iph->daddr = fl4.daddr;
|
||||||
iph->saddr = fl4.saddr;
|
iph->saddr = fl4.saddr;
|
||||||
|
iph->ttl = ttl;
|
||||||
|
|
||||||
if ((iph->ttl = tiph->ttl) == 0) {
|
if (ttl == 0) {
|
||||||
if (skb->protocol == htons(ETH_P_IP))
|
if (skb->protocol == htons(ETH_P_IP))
|
||||||
iph->ttl = old_iph->ttl;
|
iph->ttl = old_iph->ttl;
|
||||||
#if IS_ENABLED(CONFIG_IPV6)
|
#if IS_ENABLED(CONFIG_IPV6)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче