From: Patrick McHardy Date: Tue, 21 Feb 2006 21:37:35 +0000 (-0800) Subject: [NETFILTER]: Fix bridge netfilter related in xfrm_lookup X-Git-Tag: v2.6.16-rc5~54^2~5 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42cf93cd464e0df3c85d298c647411bae6d99e6e;p=linux-2.6 [NETFILTER]: Fix bridge netfilter related in xfrm_lookup The bridge-netfilter code attaches a fake dst_entry with dst->ops == NULL to purely bridged packets. When these packets are SNATed and a policy lookup is done, xfrm_lookup crashes because it tries to dereference dst->ops. Change xfrm_lookup not to dereference dst->ops before checking for the DST_NOXFRM flag and set this flag in the fake dst_entry. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 6bb0c7eb1e..e060aad862 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -90,6 +90,7 @@ static struct rtable __fake_rtable = { .dev = &__fake_net_device, .path = &__fake_rtable.u.dst, .metrics = {[RTAX_MTU - 1] = 1500}, + .flags = DST_NOXFRM, } }, .rt_flags = 0, diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 5e6b05ac12..8206025d8e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -782,7 +782,7 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, int nx = 0; int err; u32 genid; - u16 family = dst_orig->ops->family; + u16 family; u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); u32 sk_sid = security_sk_sid(sk, fl, dir); restart: @@ -796,13 +796,14 @@ restart: if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) return 0; - policy = flow_cache_lookup(fl, sk_sid, family, dir, - xfrm_policy_lookup); + policy = flow_cache_lookup(fl, sk_sid, dst_orig->ops->family, + dir, xfrm_policy_lookup); } if (!policy) return 0; + family = dst_orig->ops->family; policy->curlft.use_time = (unsigned long)xtime.tv_sec; switch (policy->action) {