]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 11:51:26 +0000 (13:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 11:51:26 +0000 (13:51 +0200)
added patches:
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

queue-3.18/series
queue-3.18/xfrm-fix-stack-access-out-of-bounds-with-config_xfrm_sub_policy.patch [new file with mode: 0644]
queue-3.18/xfrm-null-dereference-on-allocation-failure.patch [new file with mode: 0644]
queue-3.18/xfrm-oops-on-error-in-pfkey_msg2xfrm_state.patch [new file with mode: 0644]

index 2509f49196a983526320214c02eab3f249957453..e33391cd2185ebbe21c7d311e1a200a8a88e5e3f 100644 (file)
@@ -24,3 +24,6 @@ mm-numa-avoid-waiting-on-freed-migrated-pages.patch
 arm-dts-bcm5301x-correct-gic_ppi-interrupt-flags.patch
 net-korina-fix-napi-versus-resources-freeing.patch
 mtd-bcm47xxpart-limit-scanned-flash-area-on-bcm47xx-mips-only.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
diff --git a/queue-3.18/xfrm-fix-stack-access-out-of-bounds-with-config_xfrm_sub_policy.patch b/queue-3.18/xfrm-fix-stack-access-out-of-bounds-with-config_xfrm_sub_policy.patch
new file mode 100644 (file)
index 0000000..8cf421d
--- /dev/null
@@ -0,0 +1,121 @@
+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
+@@ -949,10 +949,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;
+@@ -968,12 +964,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
+@@ -1751,43 +1751,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)
+@@ -1859,16 +1822,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);
diff --git a/queue-3.18/xfrm-null-dereference-on-allocation-failure.patch b/queue-3.18/xfrm-null-dereference-on-allocation-failure.patch
new file mode 100644 (file)
index 0000000..2a9fbda
--- /dev/null
@@ -0,0 +1,34 @@
+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
+@@ -1135,6 +1135,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;
diff --git a/queue-3.18/xfrm-oops-on-error-in-pfkey_msg2xfrm_state.patch b/queue-3.18/xfrm-oops-on-error-in-pfkey_msg2xfrm_state.patch
new file mode 100644 (file)
index 0000000..27848e4
--- /dev/null
@@ -0,0 +1,71 @@
+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
+@@ -1147,8 +1147,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) {
+@@ -1167,8 +1169,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 {
+@@ -1182,8 +1186,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) {
+@@ -1227,8 +1233,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];