aboutsummaryrefslogtreecommitdiff
path: root/main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch')
-rw-r--r--main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch96
1 files changed, 96 insertions, 0 deletions
diff --git a/main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch b/main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch
new file mode 100644
index 0000000000..e1e9a655e1
--- /dev/null
+++ b/main/linux-grsec/0019-ipv4-check-rt_genid-in-dst_check.patch
@@ -0,0 +1,96 @@
1From d11a4dc18bf41719c9f0d7ed494d295dd2973b92 Mon Sep 17 00:00:00 2001
2From: =?utf8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
3Date: Thu, 18 Mar 2010 23:20:20 +0000
4Subject: [PATCH] ipv4: check rt_genid in dst_check
5
6Xfrm_dst keeps a reference to ipv4 rtable entries on each
7cached bundle. The only way to renew xfrm_dst when the underlying
8route has changed, is to implement dst_check for this. This is
9what ipv6 side does too.
10
11The problems started after 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9
12("ipsec: Fix bogus bundle flowi") which fixed a bug causing xfrm_dst
13to not get reused, until that all lookups always generated new
14xfrm_dst with new route reference and path mtu worked. But after the
15fix, the old routes started to get reused even after they were expired
16causing pmtu to break (well it would occationally work if the rtable
17gc had run recently and marked the route obsolete causing dst_check to
18get called).
19
20Signed-off-by: Timo Teras <timo.teras@iki.fi>
21Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
22Signed-off-by: David S. Miller <davem@davemloft.net>
23---
24 net/ipv4/route.c | 14 ++++++++++----
25 1 files changed, 10 insertions(+), 4 deletions(-)
26
27diff --git a/net/ipv4/route.c b/net/ipv4/route.c
28index a770df2..32d3961 100644
29--- a/net/ipv4/route.c
30+++ b/net/ipv4/route.c
31@@ -1441,7 +1441,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
32 dev_hold(rt->u.dst.dev);
33 if (rt->idev)
34 in_dev_hold(rt->idev);
35- rt->u.dst.obsolete = 0;
36+ rt->u.dst.obsolete = -1;
37 rt->u.dst.lastuse = jiffies;
38 rt->u.dst.path = &rt->u.dst;
39 rt->u.dst.neighbour = NULL;
40@@ -1506,7 +1506,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
41 struct dst_entry *ret = dst;
42
43 if (rt) {
44- if (dst->obsolete) {
45+ if (dst->obsolete > 0) {
46 ip_rt_put(rt);
47 ret = NULL;
48 } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
49@@ -1726,7 +1726,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
50
51 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
52 {
53- return NULL;
54+ if (rt_is_expired((struct rtable *)dst))
55+ return NULL;
56+ return dst;
57 }
58
59 static void ipv4_dst_destroy(struct dst_entry *dst)
60@@ -1888,7 +1890,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
61 if (!rth)
62 goto e_nobufs;
63
64- rth->u.dst.output= ip_rt_bug;
65+ rth->u.dst.output = ip_rt_bug;
66+ rth->u.dst.obsolete = -1;
67
68 atomic_set(&rth->u.dst.__refcnt, 1);
69 rth->u.dst.flags= DST_HOST;
70@@ -2054,6 +2057,7 @@ static int __mkroute_input(struct sk_buff *skb,
71 rth->fl.oif = 0;
72 rth->rt_spec_dst= spec_dst;
73
74+ rth->u.dst.obsolete = -1;
75 rth->u.dst.input = ip_forward;
76 rth->u.dst.output = ip_output;
77 rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
78@@ -2218,6 +2222,7 @@ local_input:
79 goto e_nobufs;
80
81 rth->u.dst.output= ip_rt_bug;
82+ rth->u.dst.obsolete = -1;
83 rth->rt_genid = rt_genid(net);
84
85 atomic_set(&rth->u.dst.__refcnt, 1);
86@@ -2444,6 +2449,7 @@ static int __mkroute_output(struct rtable **result,
87 rth->rt_spec_dst= fl->fl4_src;
88
89 rth->u.dst.output=ip_output;
90+ rth->u.dst.obsolete = -1;
91 rth->rt_genid = rt_genid(dev_net(dev_out));
92
93 RT_CACHE_STAT_INC(out_slow_tot);
94--
951.7.1
96