Commit 40e3012e authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
ipsec 2016-09-08

1) Fix a crash when xfrm_dump_sa returns an error.
   From Vegard Nossum.

2) Remove some incorrect WARN() on normal error handling.
   From Vegard Nossum.

3) Ignore socket policies when rebuilding hash tables,
   socket policies are not inserted into the hash tables.
   From Tobias Brunner.

4) Initialize and check tunnel pointers properly before
   we use it. From Alexey Kodanev.

5) Fix l3mdev oif setting on xfrm dst lookups.
   From David Ahern.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9dd4aaef 11d7a0bb
...@@ -29,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, ...@@ -29,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
memset(fl4, 0, sizeof(*fl4)); memset(fl4, 0, sizeof(*fl4));
fl4->daddr = daddr->a4; fl4->daddr = daddr->a4;
fl4->flowi4_tos = tos; fl4->flowi4_tos = tos;
fl4->flowi4_oif = oif; fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif);
if (saddr) if (saddr)
fl4->saddr = saddr->a4; fl4->saddr = saddr->a4;
......
...@@ -23,6 +23,7 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -23,6 +23,7 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
{ {
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
XFRM_SPI_SKB_CB(skb)->family = AF_INET6; XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr); XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
return xfrm_input(skb, nexthdr, spi, 0); return xfrm_input(skb, nexthdr, spi, 0);
......
...@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif, ...@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
int err; int err;
memset(&fl6, 0, sizeof(fl6)); memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif; fl6.flowi6_oif = l3mdev_master_ifindex_by_index(net, oif);
fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
if (saddr) if (saddr)
......
...@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) ...@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
family = XFRM_SPI_SKB_CB(skb)->family; family = XFRM_SPI_SKB_CB(skb)->family;
/* if tunnel is present override skb->mark value with tunnel i_key */ /* if tunnel is present override skb->mark value with tunnel i_key */
if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) { switch (family) {
switch (family) { case AF_INET:
case AF_INET: if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
break; break;
case AF_INET6: case AF_INET6:
if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
break; break;
}
} }
/* Allocate new secpath or COW existing one. */ /* Allocate new secpath or COW existing one. */
......
...@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work) ...@@ -626,6 +626,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
/* re-insert all policies by order of creation */ /* re-insert all policies by order of creation */
list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) {
/* skip socket policies */
continue;
}
newpos = NULL; newpos = NULL;
chain = policy_hash_bysel(net, &policy->selector, chain = policy_hash_bysel(net, &policy->selector,
policy->family, policy->family,
......
...@@ -896,7 +896,8 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb) ...@@ -896,7 +896,8 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb)
struct sock *sk = cb->skb->sk; struct sock *sk = cb->skb->sk;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
xfrm_state_walk_done(walk, net); if (cb->args[0])
xfrm_state_walk_done(walk, net);
return 0; return 0;
} }
...@@ -921,8 +922,6 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -921,8 +922,6 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
u8 proto = 0; u8 proto = 0;
int err; int err;
cb->args[0] = 1;
err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX,
xfrma_policy); xfrma_policy);
if (err < 0) if (err < 0)
...@@ -939,6 +938,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -939,6 +938,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
proto = nla_get_u8(attrs[XFRMA_PROTO]); proto = nla_get_u8(attrs[XFRMA_PROTO]);
xfrm_state_walk_init(walk, proto, filter); xfrm_state_walk_init(walk, proto, filter);
cb->args[0] = 1;
} }
(void) xfrm_state_walk(net, walk, dump_one_state, &info); (void) xfrm_state_walk(net, walk, dump_one_state, &info);
...@@ -2051,9 +2051,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -2051,9 +2051,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
if (up->hard) { if (up->hard) {
xfrm_policy_delete(xp, p->dir); xfrm_policy_delete(xp, p->dir);
xfrm_audit_policy_delete(xp, 1, true); xfrm_audit_policy_delete(xp, 1, true);
} else {
// reset the timers here?
WARN(1, "Don't know what to do with soft policy expire\n");
} }
km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid); km_policy_expired(xp, p->dir, up->hard, nlh->nlmsg_pid);
...@@ -2117,7 +2114,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -2117,7 +2114,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
err = verify_newpolicy_info(&ua->policy); err = verify_newpolicy_info(&ua->policy);
if (err) if (err)
goto bad_policy; goto free_state;
/* build an XP */ /* build an XP */
xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
...@@ -2149,8 +2146,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -2149,8 +2146,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
return 0; return 0;
bad_policy:
WARN(1, "BAD policy passed\n");
free_state: free_state:
kfree(x); kfree(x);
nomem: nomem:
......
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