]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Oct 2012 13:31:01 +0000 (06:31 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Oct 2012 13:31:01 +0000 (06:31 -0700)
added patches:
xfrm_user-ensure-user-supplied-esn-replay-window-is-valid.patch

queue-3.5/series
queue-3.5/xfrm_user-ensure-user-supplied-esn-replay-window-is-valid.patch [new file with mode: 0644]

index 0f4bdfbdeec0cef03548ee73a11c80de5e1a9352..28e7a3292551a5626bf3de7975ee9209379948a0 100644 (file)
@@ -74,3 +74,4 @@ ext4-move_extent-code-cleanup.patch
 ext4-online-defrag-is-not-supported-for-journaled-files.patch
 ext4-always-set-i_op-in-ext4_mknod.patch
 ext4-fix-fdatasync-for-files-with-only-i_size-changes.patch
+xfrm_user-ensure-user-supplied-esn-replay-window-is-valid.patch
diff --git a/queue-3.5/xfrm_user-ensure-user-supplied-esn-replay-window-is-valid.patch b/queue-3.5/xfrm_user-ensure-user-supplied-esn-replay-window-is-valid.patch
new file mode 100644 (file)
index 0000000..ea5d2cb
--- /dev/null
@@ -0,0 +1,137 @@
+From ecd7918745234e423dd87fcc0c077da557909720 Mon Sep 17 00:00:00 2001
+From: Mathias Krause <minipli@googlemail.com>
+Date: Thu, 20 Sep 2012 10:01:49 +0000
+Subject: xfrm_user: ensure user supplied esn replay window is valid
+
+From: Mathias Krause <minipli@googlemail.com>
+
+commit ecd7918745234e423dd87fcc0c077da557909720 upstream.
+
+The current code fails to ensure that the netlink message actually
+contains as many bytes as the header indicates. If a user creates a new
+state or updates an existing one but does not supply the bytes for the
+whole ESN replay window, the kernel copies random heap bytes into the
+replay bitmap, the ones happen to follow the XFRMA_REPLAY_ESN_VAL
+netlink attribute. This leads to following issues:
+
+1. The replay window has random bits set confusing the replay handling
+   code later on.
+
+2. A malicious user could use this flaw to leak up to ~3.5kB of heap
+   memory when she has access to the XFRM netlink interface (requires
+   CAP_NET_ADMIN).
+
+Known users of the ESN replay window are strongSwan and Steffen's
+iproute2 patch (<http://patchwork.ozlabs.org/patch/85962/>). The latter
+uses the interface with a bitmap supplied while the former does not.
+strongSwan is therefore prone to run into issue 1.
+
+To fix both issues without breaking existing userland allow using the
+XFRMA_REPLAY_ESN_VAL netlink attribute with either an empty bitmap or a
+fully specified one. For the former case we initialize the in-kernel
+bitmap with zero, for the latter we copy the user supplied bitmap. For
+state updates the full bitmap must be supplied.
+
+To prevent overflows in the bitmap length calculation the maximum size
+of bmp_len is limited to 128 by this patch -- resulting in a maximum
+replay window of 4096 packets. This should be sufficient for all real
+life scenarios (RFC 4303 recommends a default replay window size of 64).
+
+Signed-off-by: Mathias Krause <minipli@googlemail.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: Martin Willi <martin@revosec.ch>
+Cc: Ben Hutchings <bhutchings@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/xfrm.h |    2 ++
+ net/xfrm/xfrm_user.c |   31 +++++++++++++++++++++++++------
+ 2 files changed, 27 insertions(+), 6 deletions(-)
+
+--- a/include/linux/xfrm.h
++++ b/include/linux/xfrm.h
+@@ -84,6 +84,8 @@ struct xfrm_replay_state {
+       __u32   bitmap;
+ };
++#define XFRMA_REPLAY_ESN_MAX  4096
++
+ struct xfrm_replay_state_esn {
+       unsigned int    bmp_len;
+       __u32           oseq;
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -123,9 +123,21 @@ static inline int verify_replay(struct x
+                               struct nlattr **attrs)
+ {
+       struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
++      struct xfrm_replay_state_esn *rs;
+-      if ((p->flags & XFRM_STATE_ESN) && !rt)
+-              return -EINVAL;
++      if (p->flags & XFRM_STATE_ESN) {
++              if (!rt)
++                      return -EINVAL;
++
++              rs = nla_data(rt);
++
++              if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
++                      return -EINVAL;
++
++              if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
++                  nla_len(rt) != sizeof(*rs))
++                      return -EINVAL;
++      }
+       if (!rt)
+               return 0;
+@@ -370,14 +382,15 @@ static inline int xfrm_replay_verify_len
+                                        struct nlattr *rp)
+ {
+       struct xfrm_replay_state_esn *up;
++      int ulen;
+       if (!replay_esn || !rp)
+               return 0;
+       up = nla_data(rp);
++      ulen = xfrm_replay_state_esn_len(up);
+-      if (xfrm_replay_state_esn_len(replay_esn) !=
+-                      xfrm_replay_state_esn_len(up))
++      if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
+               return -EINVAL;
+       return 0;
+@@ -388,22 +401,28 @@ static int xfrm_alloc_replay_state_esn(s
+                                      struct nlattr *rta)
+ {
+       struct xfrm_replay_state_esn *p, *pp, *up;
++      int klen, ulen;
+       if (!rta)
+               return 0;
+       up = nla_data(rta);
++      klen = xfrm_replay_state_esn_len(up);
++      ulen = nla_len(rta) >= klen ? klen : sizeof(*up);
+-      p = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
++      p = kzalloc(klen, GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+-      pp = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
++      pp = kzalloc(klen, GFP_KERNEL);
+       if (!pp) {
+               kfree(p);
+               return -ENOMEM;
+       }
++      memcpy(p, up, ulen);
++      memcpy(pp, up, ulen);
++
+       *replay_esn = p;
+       *preplay_esn = pp;