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.
Please pull or let me know if there are problems.
Thanks!
The following changes since commit 8e6ce7ebeb34f0992f56de078c3744fb383657fa:
net: cavium: liquidio: Avoid dma_unmap_single on uninitialized ndata (2016-07-16 22:06:00 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git master
for you to fetch changes up to 11d7a0bb95eaaba1741bb24a7c3c169c82f09c7b:
xfrm: Only add l3mdev oif to dst lookups (2016-08-22 06:33:32 +0200)
----------------------------------------------------------------
Alexey Kodanev (1):
net/xfrm_input: fix possible NULL deref of tunnel.ip6->parms.i_key
David Ahern (1):
xfrm: Only add l3mdev oif to dst lookups
Tobias Brunner (1):
xfrm: Ignore socket policies when rebuilding hash tables
Vegard Nossum (3):
xfrm: fix crash in XFRM_MSG_GETSA netlink handler
xfrm: get rid of incorrect WARN
xfrm: get rid of another incorrect WARN
net/ipv4/xfrm4_policy.c | 2 +-
net/ipv6/xfrm6_input.c | 1 +
net/ipv6/xfrm6_policy.c | 2 +-
net/xfrm/xfrm_input.c | 14 +++++++-------
net/xfrm/xfrm_policy.c | 4 ++++
net/xfrm/xfrm_user.c | 13 ++++---------
6 files changed, 18 insertions(+), 18 deletions(-)
From: Vegard Nossum <redacted>
AFAICT this message is just printed whenever input validation fails.
This is a normal failure and we shouldn't be dumping the stack over it.
Looks like it was originally a printk that was maybe incorrectly
upgraded to a WARN:
commit 62db5cfd70b1ef53aa21f144a806fe3b78c84fab
Author: stephen hemminger [off-list ref]
Date: Wed May 12 06:37:06 2010 +0000
xfrm: add severity to printk
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Vegard Nossum <redacted>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_user.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
From: Vegard Nossum <redacted>
If we hit any of the error conditions inside xfrm_dump_sa(), then
xfrm_state_walk_init() never gets called. However, we still call
xfrm_state_walk_done() from xfrm_dump_sa_done(), which will crash
because the state walk was never initialized properly.
We can fix this by setting cb->args[0] only after we've processed the
first element and checking this before calling xfrm_state_walk_done().
Fixes: d3623099d3 ("ipsec: add support of limited SA dump")
Cc: Nicolas Dichtel <redacted>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Vegard Nossum <redacted>
Acked-by: Nicolas Dichtel <redacted>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_user.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
From: Vegard Nossum <redacted>
During fuzzing I regularly run into this WARN(). According to Herbert Xu,
this "certainly shouldn't be a WARN, it probably shouldn't print anything
either".
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Vegard Nossum <redacted>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_user.c | 3 ---
1 file changed, 3 deletions(-)
@@ -2051,9 +2051,6 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,if(up->hard){xfrm_policy_delete(xp,p->dir);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);
From: David Ahern <redacted>
Subash reported that commit 42a7b32b73d6 ("xfrm: Add oif to dst lookups")
broke a wifi use case that uses fib rules and xfrms. The intent of
42a7b32b73d6 was driven by VRFs with IPsec. As a compromise relax the
use of oif in xfrm lookups to L3 master devices only (ie., oif is either
an L3 master device or is enslaved to a master device).
Fixes: 42a7b32b73d6 ("xfrm: Add oif to dst lookups")
Reported-by: Subash Abhinov Kasiviswanathan <redacted>
Signed-off-by: David Ahern <redacted>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv4/xfrm4_policy.c | 2 +-
net/ipv6/xfrm6_policy.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
@@ -36,7 +36,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,interr;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;memcpy(&fl6.daddr,daddr,sizeof(fl6.daddr));if(saddr)
From: Alexey Kodanev <redacted>
Running LTP 'icmp-uni-basic.sh -6 -p ipcomp -m tunnel' test over
openvswitch + veth can trigger kernel panic:
BUG: unable to handle kernel NULL pointer dereference
at 00000000000000e0 IP: [<ffffffff8169d1d2>] xfrm_input+0x82/0x750
...
[<ffffffff816d472e>] xfrm6_rcv_spi+0x1e/0x20
[<ffffffffa082c3c2>] xfrm6_tunnel_rcv+0x42/0x50 [xfrm6_tunnel]
[<ffffffffa082727e>] tunnel6_rcv+0x3e/0x8c [tunnel6]
[<ffffffff8169f365>] ip6_input_finish+0xd5/0x430
[<ffffffff8169fc53>] ip6_input+0x33/0x90
[<ffffffff8169f1d5>] ip6_rcv_finish+0xa5/0xb0
...
It seems that tunnel.ip6 can have garbage values and also dereferenced
without a proper check, only tunnel.ip4 is being verified. Fix it by
adding one more if block for AF_INET6 and initialize tunnel.ip6 with NULL
inside xfrm6_rcv_spi() (which is similar to xfrm4_rcv_spi()).
Fixes: 049f8e2 ("xfrm: Override skb->mark with tunnel->parm.i_key in xfrm_input")
Signed-off-by: Alexey Kodanev <redacted>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv6/xfrm6_input.c | 1 +
net/xfrm/xfrm_input.c | 14 +++++++-------
2 files changed, 8 insertions(+), 7 deletions(-)
@@ -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;/* if tunnel is present override skb->mark value with tunnel i_key */-if(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4){-switch(family){-caseAF_INET:+switch(family){+caseAF_INET:+if(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)mark=be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);-break;-caseAF_INET6:+break;+caseAF_INET6:+if(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)mark=be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);-break;-}+break;}/* Allocate new secpath or COW existing one. */
From: Tobias Brunner <redacted>
Whenever thresholds are changed the hash tables are rebuilt. This is
done by enumerating all policies and hashing and inserting them into
the right table according to the thresholds and direction.
Because socket policies are also contained in net->xfrm.policy_all but
no hash tables are defined for their direction (dir + XFRM_POLICY_MAX)
this causes a NULL or invalid pointer dereference after returning from
policy_hash_bysel() if the rebuild is done while any socket policies
are installed.
Since the rebuild after changing thresholds is scheduled this crash
could even occur if the userland sets thresholds seemingly before
installing any socket policies.
Fixes: 53c2e285f970 ("xfrm: Do not hash socket policies")
Signed-off-by: Tobias Brunner <redacted>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_policy.c | 4 ++++
1 file changed, 4 insertions(+)