From: Greg Kroah-Hartman Date: Mon, 16 Mar 2015 10:37:08 +0000 (+0100) Subject: 3.14-stable patches X-Git-Tag: v3.10.72~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a209ad80c926fc56a7a055bef3934231cbb2b6a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: nilfs2-fix-potential-memory-overrun-on-inode.patch --- 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 index 00000000000..402e644f49f --- /dev/null +++ b/queue-3.14/nilfs2-fix-potential-memory-overrun-on-inode.patch @@ -0,0 +1,122 @@ +From 957ed60b53b519064a54988c4e31e0087e47d091 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Fri, 27 Feb 2015 15:51:56 -0800 +Subject: nilfs2: fix potential memory overrun on inode + +From: Ryusuke Konishi + +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 +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-3.14/series b/queue-3.14/series index c923ca8a03f..58bae9f6c64 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -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