Commit 99ba7ff4 authored by David S. Miller's avatar David S. Miller

[IPV6]: Fix some dst cache leaks.

1) icmpv6_send() and icmpv6_echo_reply() never release dst.
2) ip6_{push,flush}_pending_frames() leak np->cork.rt.
parent 0e7caa2a
...@@ -356,7 +356,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, ...@@ -356,7 +356,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); err = ip6_dst_lookup(sk, &dst, &fl);
if (err) goto out; if (err)
goto out;
if (hlimit < 0) { if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst)) if (ipv6_addr_is_multicast(&fl.fl6_dst))
...@@ -375,7 +376,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, ...@@ -375,7 +376,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_DEBUG "icmp: len problem\n"); printk(KERN_DEBUG "icmp: len problem\n");
__skb_push(skb, plen); __skb_push(skb, plen);
goto out; goto out_dst_release;
} }
idev = in6_dev_get(skb->dev); idev = in6_dev_get(skb->dev);
...@@ -396,6 +397,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, ...@@ -396,6 +397,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
out_put: out_put:
if (likely(idev != NULL)) if (likely(idev != NULL))
in6_dev_put(idev); in6_dev_put(idev);
out_dst_release:
dst_release(dst);
out: out:
icmpv6_xmit_unlock(); icmpv6_xmit_unlock();
} }
...@@ -435,8 +438,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -435,8 +438,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
fl.oif = np->mcast_oif; fl.oif = np->mcast_oif;
err = ip6_dst_lookup(sk, &dst, &fl); err = ip6_dst_lookup(sk, &dst, &fl);
if (err)
if (err) goto out; goto out;
if (hlimit < 0) { if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst)) if (ipv6_addr_is_multicast(&fl.fl6_dst))
...@@ -465,6 +468,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -465,6 +468,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
out_put: out_put:
if (likely(idev != NULL)) if (likely(idev != NULL))
in6_dev_put(idev); in6_dev_put(idev);
dst_release(dst);
out: out:
icmpv6_xmit_unlock(); icmpv6_xmit_unlock();
} }
......
...@@ -1484,6 +1484,7 @@ int ip6_push_pending_frames(struct sock *sk) ...@@ -1484,6 +1484,7 @@ int ip6_push_pending_frames(struct sock *sk)
np->cork.opt = NULL; np->cork.opt = NULL;
} }
if (np->cork.rt) { if (np->cork.rt) {
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL; np->cork.rt = NULL;
} }
if (np->cork.fl) { if (np->cork.fl) {
...@@ -1510,6 +1511,7 @@ void ip6_flush_pending_frames(struct sock *sk) ...@@ -1510,6 +1511,7 @@ void ip6_flush_pending_frames(struct sock *sk)
np->cork.opt = NULL; np->cork.opt = NULL;
} }
if (np->cork.rt) { if (np->cork.rt) {
dst_release(&np->cork.rt->u.dst);
np->cork.rt = NULL; np->cork.rt = NULL;
} }
if (np->cork.fl) { if (np->cork.fl) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment