diff options
author | Patrick McHardy <kaber@trash.net> | 2005-09-08 18:11:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-09-08 18:11:55 -0400 |
commit | e104411b82f5c4d19752c335492036abdbf5880d (patch) | |
tree | 03f26f98685689ab6bfa47d5bdbb6730f64bfadb | |
parent | cf0b450cd5176b68ac7d5bbe68aeae6bb6a5a4b8 (diff) |
[XFRM]: Always release dst_entry on error in xfrm_lookup
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 5 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 4 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 5 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 16 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 5 | ||||
-rw-r--r-- | net/ipv6/raw.c | 4 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 15 | ||||
-rw-r--r-- | net/ipv6/udp.c | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 8 |
9 files changed, 18 insertions, 48 deletions
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index f115a84a4ac6..f057025a719e 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, | |||
92 | fl.fl_ip_sport = tcph->dest; | 92 | fl.fl_ip_sport = tcph->dest; |
93 | fl.fl_ip_dport = tcph->source; | 93 | fl.fl_ip_dport = tcph->source; |
94 | 94 | ||
95 | if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) { | 95 | xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); |
96 | dst_release(&rt->u.dst); | ||
97 | rt = NULL; | ||
98 | } | ||
99 | 96 | ||
100 | return rt; | 97 | return rt; |
101 | } | 98 | } |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 157cec648032..cc518405b3e1 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -175,10 +175,8 @@ ipv4_connected: | |||
175 | if (final_p) | 175 | if (final_p) |
176 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 176 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
177 | 177 | ||
178 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 178 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
179 | dst_release(dst); | ||
180 | goto out; | 179 | goto out; |
181 | } | ||
182 | 180 | ||
183 | /* source address lookup done in ip6_dst_lookup */ | 181 | /* source address lookup done in ip6_dst_lookup */ |
184 | 182 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 34e99c55e856..b7185fb3377c 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
374 | if (err) | 374 | if (err) |
375 | goto out; | 375 | goto out; |
376 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 376 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
377 | goto out_dst_release; | 377 | goto out; |
378 | 378 | ||
379 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 379 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
380 | hlimit = np->mcast_hops; | 380 | hlimit = np->mcast_hops; |
@@ -469,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
469 | if (err) | 469 | if (err) |
470 | goto out; | 470 | goto out; |
471 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 471 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
472 | goto out_dst_release; | 472 | goto out; |
473 | 473 | ||
474 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 474 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
475 | hlimit = np->mcast_hops; | 475 | hlimit = np->mcast_hops; |
@@ -505,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
505 | out_put: | 505 | out_put: |
506 | if (likely(idev != NULL)) | 506 | if (likely(idev != NULL)) |
507 | in6_dev_put(idev); | 507 | in6_dev_put(idev); |
508 | out_dst_release: | ||
509 | dst_release(dst); | 508 | dst_release(dst); |
510 | out: | 509 | out: |
511 | icmpv6_xmit_unlock(); | 510 | icmpv6_xmit_unlock(); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index a7eae30f4554..555a31347eda 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -447,10 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
447 | return; | 447 | return; |
448 | 448 | ||
449 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 449 | err = xfrm_lookup(&dst, &fl, NULL, 0); |
450 | if (err < 0) { | 450 | if (err < 0) |
451 | dst_release(dst); | ||
452 | return; | 451 | return; |
453 | } | ||
454 | 452 | ||
455 | if (inc_opt) { | 453 | if (inc_opt) { |
456 | if (dev->addr_len) | 454 | if (dev->addr_len) |
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, | |||
539 | return; | 537 | return; |
540 | 538 | ||
541 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 539 | err = xfrm_lookup(&dst, &fl, NULL, 0); |
542 | if (err < 0) { | 540 | if (err < 0) |
543 | dst_release(dst); | ||
544 | return; | 541 | return; |
545 | } | ||
546 | 542 | ||
547 | len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); | 543 | len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); |
548 | send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); | 544 | send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); |
@@ -616,10 +612,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, | |||
616 | return; | 612 | return; |
617 | 613 | ||
618 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 614 | err = xfrm_lookup(&dst, &fl, NULL, 0); |
619 | if (err < 0) { | 615 | if (err < 0) |
620 | dst_release(dst); | ||
621 | return; | 616 | return; |
622 | } | ||
623 | 617 | ||
624 | len = sizeof(struct icmp6hdr); | 618 | len = sizeof(struct icmp6hdr); |
625 | if (dev->addr_len) | 619 | if (dev->addr_len) |
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1353 | return; | 1347 | return; |
1354 | 1348 | ||
1355 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 1349 | err = xfrm_lookup(&dst, &fl, NULL, 0); |
1356 | if (err) { | 1350 | if (err) |
1357 | dst_release(dst); | ||
1358 | return; | 1351 | return; |
1359 | } | ||
1360 | 1352 | ||
1361 | rt = (struct rt6_info *) dst; | 1353 | rt = (struct rt6_info *) dst; |
1362 | 1354 | ||
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 14316c3ebde4..b03e87adca93 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb) | |||
100 | dst = ip6_route_output(NULL, &fl); | 100 | dst = ip6_route_output(NULL, &fl); |
101 | if (dst == NULL) | 101 | if (dst == NULL) |
102 | return; | 102 | return; |
103 | if (dst->error || | 103 | if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) |
104 | xfrm_lookup(&dst, &fl, NULL, 0)) { | ||
105 | dst_release(dst); | ||
106 | return; | 104 | return; |
107 | } | ||
108 | 105 | ||
109 | hh_len = (dst->dev->hard_header_len + 15)&~15; | 106 | hh_len = (dst->dev->hard_header_len + 15)&~15; |
110 | nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr) | 107 | nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr) |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 2ad37893334a..5aa3691c578d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
782 | if (final_p) | 782 | if (final_p) |
783 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 783 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
784 | 784 | ||
785 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 785 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
786 | dst_release(dst); | ||
787 | goto out; | 786 | goto out; |
788 | } | ||
789 | 787 | ||
790 | if (hlimit < 0) { | 788 | if (hlimit < 0) { |
791 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) | 789 | if (ipv6_addr_is_multicast(&fl.fl6_dst)) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 246414b27d0e..80643e6b346b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
632 | if (final_p) | 632 | if (final_p) |
633 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 633 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
634 | 634 | ||
635 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 635 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
636 | dst_release(dst); | ||
637 | goto failure; | 636 | goto failure; |
638 | } | ||
639 | 637 | ||
640 | if (saddr == NULL) { | 638 | if (saddr == NULL) { |
641 | saddr = &fl.fl6_src; | 639 | saddr = &fl.fl6_src; |
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
888 | } | 886 | } |
889 | 887 | ||
890 | done: | 888 | done: |
891 | dst_release(dst); | ||
892 | if (opt && opt != np->opt) | 889 | if (opt && opt != np->opt) |
893 | sock_kfree_s(sk, opt, opt->tot_len); | 890 | sock_kfree_s(sk, opt, opt->tot_len); |
894 | return err; | 891 | return err; |
@@ -1000,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb) | |||
1000 | /* sk = NULL, but it is safe for now. RST socket required. */ | 997 | /* sk = NULL, but it is safe for now. RST socket required. */ |
1001 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 998 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
1002 | 999 | ||
1003 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { | 1000 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) |
1004 | dst_release(buff->dst); | ||
1005 | return; | 1001 | return; |
1006 | } | ||
1007 | 1002 | ||
1008 | ip6_xmit(NULL, buff, &fl, NULL, 0); | 1003 | ip6_xmit(NULL, buff, &fl, NULL, 0); |
1009 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 1004 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); |
@@ -1067,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1067 | fl.fl_ip_sport = t1->source; | 1062 | fl.fl_ip_sport = t1->source; |
1068 | 1063 | ||
1069 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 1064 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
1070 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { | 1065 | if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) |
1071 | dst_release(buff->dst); | ||
1072 | return; | 1066 | return; |
1073 | } | ||
1074 | ip6_xmit(NULL, buff, &fl, NULL, 0); | 1067 | ip6_xmit(NULL, buff, &fl, NULL, 0); |
1075 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); | 1068 | TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); |
1076 | return; | 1069 | return; |
@@ -1733,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk) | |||
1733 | 1726 | ||
1734 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 1727 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { |
1735 | sk->sk_err_soft = -err; | 1728 | sk->sk_err_soft = -err; |
1736 | dst_release(dst); | ||
1737 | return err; | 1729 | return err; |
1738 | } | 1730 | } |
1739 | 1731 | ||
@@ -1786,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) | |||
1786 | 1778 | ||
1787 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | 1779 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { |
1788 | sk->sk_route_caps = 0; | 1780 | sk->sk_route_caps = 0; |
1789 | dst_release(dst); | ||
1790 | return err; | 1781 | return err; |
1791 | } | 1782 | } |
1792 | 1783 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index f5ae14810a70..69b146843a20 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -799,10 +799,8 @@ do_udp_sendmsg: | |||
799 | if (final_p) | 799 | if (final_p) |
800 | ipv6_addr_copy(&fl->fl6_dst, final_p); | 800 | ipv6_addr_copy(&fl->fl6_dst, final_p); |
801 | 801 | ||
802 | if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) { | 802 | if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) |
803 | dst_release(dst); | ||
804 | goto out; | 803 | goto out; |
805 | } | ||
806 | 804 | ||
807 | if (hlimit < 0) { | 805 | if (hlimit < 0) { |
808 | if (ipv6_addr_is_multicast(&fl->fl6_dst)) | 806 | if (ipv6_addr_is_multicast(&fl->fl6_dst)) |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 83c8135e1764..fda737d77edc 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -765,8 +765,8 @@ restart: | |||
765 | switch (policy->action) { | 765 | switch (policy->action) { |
766 | case XFRM_POLICY_BLOCK: | 766 | case XFRM_POLICY_BLOCK: |
767 | /* Prohibit the flow */ | 767 | /* Prohibit the flow */ |
768 | xfrm_pol_put(policy); | 768 | err = -EPERM; |
769 | return -EPERM; | 769 | goto error; |
770 | 770 | ||
771 | case XFRM_POLICY_ALLOW: | 771 | case XFRM_POLICY_ALLOW: |
772 | if (policy->xfrm_nr == 0) { | 772 | if (policy->xfrm_nr == 0) { |
@@ -782,8 +782,8 @@ restart: | |||
782 | */ | 782 | */ |
783 | dst = xfrm_find_bundle(fl, policy, family); | 783 | dst = xfrm_find_bundle(fl, policy, family); |
784 | if (IS_ERR(dst)) { | 784 | if (IS_ERR(dst)) { |
785 | xfrm_pol_put(policy); | 785 | err = PTR_ERR(dst); |
786 | return PTR_ERR(dst); | 786 | goto error; |
787 | } | 787 | } |
788 | 788 | ||
789 | if (dst) | 789 | if (dst) |