]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2015 10:37:08 +0000 (11:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2015 10:37:08 +0000 (11:37 +0100)
added patches:
nilfs2-fix-potential-memory-overrun-on-inode.patch

queue-3.14/nilfs2-fix-potential-memory-overrun-on-inode.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/nilfs2-fix-potential-memory-overrun-on-inode.patch b/queue-3.14/nilfs2-fix-potential-memory-overrun-on-inode.patch
new file mode 100644 (file)
index 0000000..402e644
--- /dev/null
@@ -0,0 +1,122 @@
+From 957ed60b53b519064a54988c4e31e0087e47d091 Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Date: Fri, 27 Feb 2015 15:51:56 -0800
+Subject: nilfs2: fix potential memory overrun on inode
+
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+
+commit 957ed60b53b519064a54988c4e31e0087e47d091 upstream.
+
+Each inode of nilfs2 stores a root node of a b-tree, and it turned out to
+have a memory overrun issue:
+
+Each b-tree node of nilfs2 stores a set of key-value pairs and the number
+of them (in "bn_nchildren" member of nilfs_btree_node struct), as well as
+a few other "bn_*" members.
+
+Since the value of "bn_nchildren" is used for operations on the key-values
+within the b-tree node, it can cause memory access overrun if a large
+number is incorrectly set to "bn_nchildren".
+
+For instance, nilfs_btree_node_lookup() function determines the range of
+binary search with it, and too large "bn_nchildren" leads
+nilfs_btree_node_get_key() in that function to overrun.
+
+As for intermediate b-tree nodes, this is prevented by a sanity check
+performed when each node is read from a drive, however, no sanity check
+has been done for root nodes stored in inodes.
+
+This patch fixes the issue by adding missing sanity check against b-tree
+root nodes so that it's called when on-memory inodes are read from ifile,
+inode metadata file.
+
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nilfs2/btree.c |   47 ++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 44 insertions(+), 3 deletions(-)
+
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -31,6 +31,8 @@
+ #include "alloc.h"
+ #include "dat.h"
++static void __nilfs_btree_init(struct nilfs_bmap *bmap);
++
+ static struct nilfs_btree_path *nilfs_btree_alloc_path(void)
+ {
+       struct nilfs_btree_path *path;
+@@ -368,6 +370,34 @@ static int nilfs_btree_node_broken(const
+       return ret;
+ }
++/**
++ * nilfs_btree_root_broken - verify consistency of btree root node
++ * @node: btree root node to be examined
++ * @ino: inode number
++ *
++ * Return Value: If node is broken, 1 is returned. Otherwise, 0 is returned.
++ */
++static int nilfs_btree_root_broken(const struct nilfs_btree_node *node,
++                                 unsigned long ino)
++{
++      int level, flags, nchildren;
++      int ret = 0;
++
++      level = nilfs_btree_node_get_level(node);
++      flags = nilfs_btree_node_get_flags(node);
++      nchildren = nilfs_btree_node_get_nchildren(node);
++
++      if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
++                   level > NILFS_BTREE_LEVEL_MAX ||
++                   nchildren < 0 ||
++                   nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) {
++              pr_crit("NILFS: bad btree root (inode number=%lu): level = %d, flags = 0x%x, nchildren = %d\n",
++                      ino, level, flags, nchildren);
++              ret = 1;
++      }
++      return ret;
++}
++
+ int nilfs_btree_broken_node_block(struct buffer_head *bh)
+ {
+       int ret;
+@@ -1713,7 +1743,7 @@ nilfs_btree_commit_convert_and_insert(st
+       /* convert and insert */
+       dat = NILFS_BMAP_USE_VBN(btree) ? nilfs_bmap_get_dat(btree) : NULL;
+-      nilfs_btree_init(btree);
++      __nilfs_btree_init(btree);
+       if (nreq != NULL) {
+               nilfs_bmap_commit_alloc_ptr(btree, dreq, dat);
+               nilfs_bmap_commit_alloc_ptr(btree, nreq, dat);
+@@ -2294,12 +2324,23 @@ static const struct nilfs_bmap_operation
+       .bop_gather_data        =       NULL,
+ };
+-int nilfs_btree_init(struct nilfs_bmap *bmap)
++static void __nilfs_btree_init(struct nilfs_bmap *bmap)
+ {
+       bmap->b_ops = &nilfs_btree_ops;
+       bmap->b_nchildren_per_block =
+               NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(bmap));
+-      return 0;
++}
++
++int nilfs_btree_init(struct nilfs_bmap *bmap)
++{
++      int ret = 0;
++
++      __nilfs_btree_init(bmap);
++
++      if (nilfs_btree_root_broken(nilfs_btree_get_root(bmap),
++                                  bmap->b_inode->i_ino))
++              ret = -EIO;
++      return ret;
+ }
+ void nilfs_btree_init_gc(struct nilfs_bmap *bmap)
index c923ca8a03f347bc5f28b8c8320ecae7dc0e4c5b..58bae9f6c6428b3f487066a9f14c3492f3c5539f 100644 (file)
@@ -71,3 +71,4 @@ ib-qib-do-not-write-eeprom.patch
 ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch
 ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch
 ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch
+nilfs2-fix-potential-memory-overrun-on-inode.patch