Resolves: rhbz 892060
Backport of upstream commit ecd9883724b78cc72ed92c98bcb1a46c764fff21
This commit is contained in:
parent
6b1ca21dd3
commit
445e22c317
|
@ -0,0 +1,134 @@
|
|||
diff -up ./include/net/dst.h.orig ./include/net/dst.h
|
||||
--- ./include/net/dst.h.orig 2012-12-10 22:30:57.000000000 -0500
|
||||
+++ ./include/net/dst.h 2013-02-20 09:42:49.541777989 -0500
|
||||
@@ -36,13 +36,9 @@ struct dst_entry {
|
||||
struct net_device *dev;
|
||||
struct dst_ops *ops;
|
||||
unsigned long _metrics;
|
||||
- union {
|
||||
- unsigned long expires;
|
||||
- /* point to where the dst_entry copied from */
|
||||
- struct dst_entry *from;
|
||||
- };
|
||||
+ unsigned long expires;
|
||||
struct dst_entry *path;
|
||||
- void *__pad0;
|
||||
+ struct dst_entry *from;
|
||||
#ifdef CONFIG_XFRM
|
||||
struct xfrm_state *xfrm;
|
||||
#else
|
||||
diff -up ./include/net/ip6_fib.h.orig ./include/net/ip6_fib.h
|
||||
--- ./include/net/ip6_fib.h.orig 2012-12-10 22:30:57.000000000 -0500
|
||||
+++ ./include/net/ip6_fib.h 2013-02-20 09:42:49.597779552 -0500
|
||||
@@ -157,50 +157,35 @@ static inline struct inet6_dev *ip6_dst_
|
||||
|
||||
static inline void rt6_clean_expires(struct rt6_info *rt)
|
||||
{
|
||||
- if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
|
||||
- dst_release(rt->dst.from);
|
||||
-
|
||||
rt->rt6i_flags &= ~RTF_EXPIRES;
|
||||
- rt->dst.from = NULL;
|
||||
}
|
||||
|
||||
static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires)
|
||||
{
|
||||
- if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from)
|
||||
- dst_release(rt->dst.from);
|
||||
-
|
||||
- rt->rt6i_flags |= RTF_EXPIRES;
|
||||
rt->dst.expires = expires;
|
||||
+ rt->rt6i_flags |= RTF_EXPIRES;
|
||||
}
|
||||
|
||||
-static inline void rt6_update_expires(struct rt6_info *rt, int timeout)
|
||||
+static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
|
||||
{
|
||||
- if (!(rt->rt6i_flags & RTF_EXPIRES)) {
|
||||
- if (rt->dst.from)
|
||||
- dst_release(rt->dst.from);
|
||||
- /* dst_set_expires relies on expires == 0
|
||||
- * if it has not been set previously.
|
||||
- */
|
||||
- rt->dst.expires = 0;
|
||||
- }
|
||||
+ struct rt6_info *rt;
|
||||
|
||||
- dst_set_expires(&rt->dst, timeout);
|
||||
- rt->rt6i_flags |= RTF_EXPIRES;
|
||||
+ for (rt = rt0; rt && !(rt->rt6i_flags & RTF_EXPIRES);
|
||||
+ rt = (struct rt6_info *)rt->dst.from);
|
||||
+ if (rt && rt != rt0)
|
||||
+ rt0->dst.expires = rt->dst.expires;
|
||||
+
|
||||
+ dst_set_expires(&rt0->dst, timeout);
|
||||
+ rt0->rt6i_flags |= RTF_EXPIRES;
|
||||
}
|
||||
|
||||
static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
|
||||
{
|
||||
struct dst_entry *new = (struct dst_entry *) from;
|
||||
|
||||
- if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) {
|
||||
- if (new == rt->dst.from)
|
||||
- return;
|
||||
- dst_release(rt->dst.from);
|
||||
- }
|
||||
-
|
||||
rt->rt6i_flags &= ~RTF_EXPIRES;
|
||||
- rt->dst.from = new;
|
||||
dst_hold(new);
|
||||
+ rt->dst.from = new;
|
||||
}
|
||||
|
||||
struct fib6_walker_t {
|
||||
diff -up ./net/core/dst.c.orig ./net/core/dst.c
|
||||
--- ./net/core/dst.c.orig 2012-12-10 22:30:57.000000000 -0500
|
||||
+++ ./net/core/dst.c 2013-02-20 09:42:49.984790357 -0500
|
||||
@@ -179,6 +179,7 @@ void *dst_alloc(struct dst_ops *ops, str
|
||||
dst_init_metrics(dst, dst_default_metrics, true);
|
||||
dst->expires = 0UL;
|
||||
dst->path = dst;
|
||||
+ dst->from = NULL;
|
||||
#ifdef CONFIG_XFRM
|
||||
dst->xfrm = NULL;
|
||||
#endif
|
||||
diff -up ./net/ipv6/route.c.orig ./net/ipv6/route.c
|
||||
--- ./net/ipv6/route.c.orig 2012-12-10 22:30:57.000000000 -0500
|
||||
+++ ./net/ipv6/route.c 2013-02-20 09:42:50.238797449 -0500
|
||||
@@ -297,6 +297,7 @@ static void ip6_dst_destroy(struct dst_e
|
||||
{
|
||||
struct rt6_info *rt = (struct rt6_info *)dst;
|
||||
struct inet6_dev *idev = rt->rt6i_idev;
|
||||
+ struct dst_entry *from = dst->from;
|
||||
|
||||
if (rt->n)
|
||||
neigh_release(rt->n);
|
||||
@@ -309,8 +310,8 @@ static void ip6_dst_destroy(struct dst_e
|
||||
in6_dev_put(idev);
|
||||
}
|
||||
|
||||
- if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
|
||||
- dst_release(dst->from);
|
||||
+ dst->from = NULL;
|
||||
+ dst_release(from);
|
||||
|
||||
if (rt6_has_peer(rt)) {
|
||||
struct inet_peer *peer = rt6_peer_ptr(rt);
|
||||
@@ -998,7 +999,6 @@ struct dst_entry *ip6_blackhole_route(st
|
||||
|
||||
rt->rt6i_gateway = ort->rt6i_gateway;
|
||||
rt->rt6i_flags = ort->rt6i_flags;
|
||||
- rt6_clean_expires(rt);
|
||||
rt->rt6i_metric = 0;
|
||||
|
||||
memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
|
||||
@@ -1814,8 +1814,6 @@ static struct rt6_info *ip6_rt_copy(stru
|
||||
if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
|
||||
(RTF_DEFAULT | RTF_ADDRCONF))
|
||||
rt6_set_from(rt, ort);
|
||||
- else
|
||||
- rt6_clean_expires(rt);
|
||||
rt->rt6i_metric = 0;
|
||||
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
|
@ -807,6 +807,9 @@ Patch23000: silence-brcmsmac-warning.patch
|
|||
#rhbz 812111
|
||||
Patch24000: alps-v2-3.7.patch
|
||||
|
||||
#rhbz 892060
|
||||
Patch24001: ipv6-dst-from-ptr-race.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
%endif
|
||||
|
@ -1547,6 +1550,9 @@ ApplyPatch perf-hists-Fix-period-symbol_conf.field_sep-display.patch
|
|||
#rhbz 812111
|
||||
ApplyPatch alps-v2-3.7.patch
|
||||
|
||||
#rhbz 892060
|
||||
ApplyPatch ipv6-dst-from-ptr-race.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
|
@ -2410,6 +2416,9 @@ fi
|
|||
# ||----w |
|
||||
# || ||
|
||||
%changelog
|
||||
* Thu Feb 21 2013 Neil Horman <nhorman@redhat.com>
|
||||
- Fix crash from race in ipv6 dst entries (rhbz 892060)
|
||||
|
||||
* Wed Feb 20 2013 Josh Boyer <jwboyer@redhat.com>
|
||||
- Fix perf report field separator issue (rhbz 906055)
|
||||
- Fix oops from acpi_rsdp setup in secure-boot patchset (rhbz 906225)
|
||||
|
|
Loading…
Reference in New Issue