pinctrl-amd-use-regular-interrupt-instead-of-chained.patch
mm-vmalloc.c-huge-vmap-fail-gracefully-on-unexpected-huge-vmap-mappings.patch
xen-blkback-don-t-free-be-structure-too-early.patch
+xfrm6-fix-ipv6-payload_len-in-xfrm6_transport_finish.patch
+xfrm-move-xfrm_garbage_collect-out-of-xfrm_policy_flush.patch
+xfrm-fix-stack-access-out-of-bounds-with-config_xfrm_sub_policy.patch
+xfrm-null-dereference-on-allocation-failure.patch
+xfrm-oops-on-error-in-pfkey_msg2xfrm_state.patch
--- /dev/null
+From 9b3eb54106cf6acd03f07cf0ab01c13676a226c2 Mon Sep 17 00:00:00 2001
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Wed, 3 May 2017 16:43:19 +0200
+Subject: xfrm: fix stack access out of bounds with CONFIG_XFRM_SUB_POLICY
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+commit 9b3eb54106cf6acd03f07cf0ab01c13676a226c2 upstream.
+
+When CONFIG_XFRM_SUB_POLICY=y, xfrm_dst stores a copy of the flowi for
+that dst. Unfortunately, the code that allocates and fills this copy
+doesn't care about what type of flowi (flowi, flowi4, flowi6) gets
+passed. In multiple code paths (from raw_sendmsg, from TCP when
+replying to a FIN, in vxlan, geneve, and gre), the flowi that gets
+passed to xfrm is actually an on-stack flowi4, so we end up reading
+stuff from the stack past the end of the flowi4 struct.
+
+Since xfrm_dst->origin isn't used anywhere following commit
+ca116922afa8 ("xfrm: Eliminate "fl" and "pol" args to
+xfrm_bundle_ok()."), just get rid of it. xfrm_dst->partner isn't used
+either, so get rid of that too.
+
+Fixes: 9d6ec938019c ("ipv4: Use flowi4 in public route lookup interfaces.")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/xfrm.h | 10 ----------
+ net/xfrm/xfrm_policy.c | 47 -----------------------------------------------
+ 2 files changed, 57 deletions(-)
+
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -945,10 +945,6 @@ struct xfrm_dst {
+ struct flow_cache_object flo;
+ struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
+ int num_pols, num_xfrms;
+-#ifdef CONFIG_XFRM_SUB_POLICY
+- struct flowi *origin;
+- struct xfrm_selector *partner;
+-#endif
+ u32 xfrm_genid;
+ u32 policy_genid;
+ u32 route_mtu_cached;
+@@ -964,12 +960,6 @@ static inline void xfrm_dst_destroy(stru
+ dst_release(xdst->route);
+ if (likely(xdst->u.dst.xfrm))
+ xfrm_state_put(xdst->u.dst.xfrm);
+-#ifdef CONFIG_XFRM_SUB_POLICY
+- kfree(xdst->origin);
+- xdst->origin = NULL;
+- kfree(xdst->partner);
+- xdst->partner = NULL;
+-#endif
+ }
+ #endif
+
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1793,43 +1793,6 @@ free_dst:
+ goto out;
+ }
+
+-#ifdef CONFIG_XFRM_SUB_POLICY
+-static int xfrm_dst_alloc_copy(void **target, const void *src, int size)
+-{
+- if (!*target) {
+- *target = kmalloc(size, GFP_ATOMIC);
+- if (!*target)
+- return -ENOMEM;
+- }
+-
+- memcpy(*target, src, size);
+- return 0;
+-}
+-#endif
+-
+-static int xfrm_dst_update_parent(struct dst_entry *dst,
+- const struct xfrm_selector *sel)
+-{
+-#ifdef CONFIG_XFRM_SUB_POLICY
+- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+- return xfrm_dst_alloc_copy((void **)&(xdst->partner),
+- sel, sizeof(*sel));
+-#else
+- return 0;
+-#endif
+-}
+-
+-static int xfrm_dst_update_origin(struct dst_entry *dst,
+- const struct flowi *fl)
+-{
+-#ifdef CONFIG_XFRM_SUB_POLICY
+- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+- return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
+-#else
+- return 0;
+-#endif
+-}
+-
+ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
+ struct xfrm_policy **pols,
+ int *num_pols, int *num_xfrms)
+@@ -1901,16 +1864,6 @@ xfrm_resolve_and_create_bundle(struct xf
+
+ xdst = (struct xfrm_dst *)dst;
+ xdst->num_xfrms = err;
+- if (num_pols > 1)
+- err = xfrm_dst_update_parent(dst, &pols[1]->selector);
+- else
+- err = xfrm_dst_update_origin(dst, fl);
+- if (unlikely(err)) {
+- dst_free(dst);
+- XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+- return ERR_PTR(err);
+- }
+-
+ xdst->num_pols = num_pols;
+ memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
+ xdst->policy_genid = atomic_read(&pols[0]->genid);
--- /dev/null
+From 138437f591dd9a42d53c6fed1a3c85e02678851c Mon Sep 17 00:00:00 2001
+From: Hangbin Liu <liuhangbin@gmail.com>
+Date: Sun, 11 Jun 2017 09:44:20 +0800
+Subject: xfrm: move xfrm_garbage_collect out of xfrm_policy_flush
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+commit 138437f591dd9a42d53c6fed1a3c85e02678851c upstream.
+
+Now we will force to do garbage collection if any policy removed in
+xfrm_policy_flush(). But during xfrm_net_exit(). We call flow_cache_fini()
+first and set set fc->percpu to NULL. Then after we call xfrm_policy_fini()
+-> frxm_policy_flush() -> flow_cache_flush(), we will get NULL pointer
+dereference when check percpu_empty. The code path looks like:
+
+flow_cache_fini()
+ - fc->percpu = NULL
+xfrm_policy_fini()
+ - xfrm_policy_flush()
+ - xfrm_garbage_collect()
+ - flow_cache_flush()
+ - flow_cache_percpu_empty()
+ - fcp = per_cpu_ptr(fc->percpu, cpu)
+
+To reproduce, just add ipsec in netns and then remove the netns.
+
+v2:
+As Xin Long suggested, since only two other places need to call it. move
+xfrm_garbage_collect() outside xfrm_policy_flush().
+
+v3:
+Fix subject mismatch after v2 fix.
+
+Fixes: 35db06912189 ("xfrm: do the garbage collection after flushing policy")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/key/af_key.c | 2 ++
+ net/xfrm/xfrm_policy.c | 4 ----
+ net/xfrm/xfrm_user.c | 1 +
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2755,6 +2755,8 @@ static int pfkey_spdflush(struct sock *s
+ int err, err2;
+
+ err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, true);
++ if (!err)
++ xfrm_garbage_collect(net);
+ err2 = unicast_flush_resp(sk, hdr);
+ if (err || err2) {
+ if (err == -ESRCH) /* empty table - old silent behavior */
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1006,10 +1006,6 @@ int xfrm_policy_flush(struct net *net, u
+ err = -ESRCH;
+ out:
+ spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
+-
+- if (cnt)
+- xfrm_garbage_collect(net);
+-
+ return err;
+ }
+ EXPORT_SYMBOL(xfrm_policy_flush);
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -1999,6 +1999,7 @@ static int xfrm_flush_policy(struct sk_b
+ return 0;
+ return err;
+ }
++ xfrm_garbage_collect(net);
+
+ c.data.type = type;
+ c.event = nlh->nlmsg_type;
--- /dev/null
+From e747f64336fc15e1c823344942923195b800aa1e Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 14 Jun 2017 13:35:37 +0300
+Subject: xfrm: NULL dereference on allocation failure
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit e747f64336fc15e1c823344942923195b800aa1e upstream.
+
+The default error code in pfkey_msg2xfrm_state() is -ENOBUFS. We
+added a new call to security_xfrm_state_alloc() which sets "err" to zero
+so there several places where we can return ERR_PTR(0) if kmalloc()
+fails. The caller is expecting error pointers so it leads to a NULL
+dereference.
+
+Fixes: df71837d5024 ("[LSM-IPSec]: Security association restriction.")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/key/af_key.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -1157,6 +1157,7 @@ static struct xfrm_state * pfkey_msg2xfr
+ goto out;
+ }
+
++ err = -ENOBUFS;
+ key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
+ if (sa->sadb_sa_auth) {
+ int keysize = 0;
--- /dev/null
+From 1e3d0c2c70cd3edb5deed186c5f5c75f2b84a633 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 14 Jun 2017 13:34:05 +0300
+Subject: xfrm: Oops on error in pfkey_msg2xfrm_state()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 1e3d0c2c70cd3edb5deed186c5f5c75f2b84a633 upstream.
+
+There are some missing error codes here so we accidentally return NULL
+instead of an error pointer. It results in a NULL pointer dereference.
+
+Fixes: df71837d5024 ("[LSM-IPSec]: Security association restriction.")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/key/af_key.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -1169,8 +1169,10 @@ static struct xfrm_state * pfkey_msg2xfr
+ if (key)
+ keysize = (key->sadb_key_bits + 7) / 8;
+ x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
+- if (!x->aalg)
++ if (!x->aalg) {
++ err = -ENOMEM;
+ goto out;
++ }
+ strcpy(x->aalg->alg_name, a->name);
+ x->aalg->alg_key_len = 0;
+ if (key) {
+@@ -1189,8 +1191,10 @@ static struct xfrm_state * pfkey_msg2xfr
+ goto out;
+ }
+ x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
+- if (!x->calg)
++ if (!x->calg) {
++ err = -ENOMEM;
+ goto out;
++ }
+ strcpy(x->calg->alg_name, a->name);
+ x->props.calgo = sa->sadb_sa_encrypt;
+ } else {
+@@ -1204,8 +1208,10 @@ static struct xfrm_state * pfkey_msg2xfr
+ if (key)
+ keysize = (key->sadb_key_bits + 7) / 8;
+ x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
+- if (!x->ealg)
++ if (!x->ealg) {
++ err = -ENOMEM;
+ goto out;
++ }
+ strcpy(x->ealg->alg_name, a->name);
+ x->ealg->alg_key_len = 0;
+ if (key) {
+@@ -1250,8 +1256,10 @@ static struct xfrm_state * pfkey_msg2xfr
+ struct xfrm_encap_tmpl *natt;
+
+ x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
+- if (!x->encap)
++ if (!x->encap) {
++ err = -ENOMEM;
+ goto out;
++ }
+
+ natt = x->encap;
+ n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
--- /dev/null
+From 7c88e21aefcf86fb41b48b2e04528db5a30fbe18 Mon Sep 17 00:00:00 2001
+From: Yossi Kuperman <yossiku@mellanox.com>
+Date: Thu, 22 Jun 2017 11:37:10 +0300
+Subject: xfrm6: Fix IPv6 payload_len in xfrm6_transport_finish
+
+From: Yossi Kuperman <yossiku@mellanox.com>
+
+commit 7c88e21aefcf86fb41b48b2e04528db5a30fbe18 upstream.
+
+IPv6 payload length indicates the size of the payload, including any
+extension headers.
+
+In xfrm6_transport_finish, ipv6_hdr(skb)->payload_len is set to the
+payload size only, regardless of the presence of any extension headers.
+After ESP GRO transport mode decapsulation, ipv6_rcv trims the packet
+according to the wrong payload_len, thus corrupting the packet.
+
+Set payload_len to account for extension headers as well.
+
+Fixes: 7785bba299a8 ("esp: Add a software GRO codepath")
+Signed-off-by: Yossi Kuperman <yossiku@mellanox.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/xfrm6_input.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/xfrm6_input.c
++++ b/net/ipv6/xfrm6_input.c
+@@ -43,8 +43,8 @@ int xfrm6_transport_finish(struct sk_buf
+ return 1;
+ #endif
+
+- ipv6_hdr(skb)->payload_len = htons(skb->len);
+ __skb_push(skb, skb->data - skb_network_header(skb));
++ ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+
+ if (xo && (xo->flags & XFRM_GRO)) {
+ skb_mac_header_rebuild(skb);