potential memory corruption in check_leaf()

Artem Bityutskiy dedekind1 at gmail.com
Tue Nov 25 07:00:54 PST 2014


On Thu, 2014-11-06 at 13:09 +0300, Dan Carpenter wrote:
>   1988                  ubifs_err("bad leaf length %d (LEB %d:%d)",
>   1989                            zbr->len, zbr->lnum, zbr->offs);
>   1990                  return -EINVAL;
>   1991          }

Yes, this code is a small sanity check. zbr->len is supposed to be the
length of whatever node type is referred by this znode branch.


>   1993          node = kmalloc(zbr->len, GFP_NOFS);
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Allocate node.

Supposedly we allocate enough to store the node we refer to.

>   2031          if (type == UBIFS_DATA_KEY) {
>   2032                  long long blk_offs;
>   2033                  struct ubifs_data_node *dn = node;
>                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> But it's not large enough for "dn".

Well, this should not happen, but let's add an assert here to check that
we have enough space for 'dn'.

Something like this.


>From 6785baa1697c15a51408e7317709cbf078604695 Mon Sep 17 00:00:00 2001
From: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Date: Tue, 25 Nov 2014 16:41:26 +0200
Subject: [PATCH] UBIFS: add a couple of extra asserts

... to catch possible memory corruptions.

Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
---
 fs/ubifs/debug.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 7ed13e1..4cfb3e8 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2032,6 +2032,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
 		long long blk_offs;
 		struct ubifs_data_node *dn = node;
 
+		ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ);
+
 		/*
 		 * Search the inode node this data node belongs to and insert
 		 * it to the RB-tree of inodes.
@@ -2060,6 +2062,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
 		struct ubifs_dent_node *dent = node;
 		struct fsck_inode *fscki1;
 
+		ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ);
+
 		err = ubifs_validate_entry(c, dent);
 		if (err)
 			goto out_dump;
-- 
1.9.3





More information about the linux-mtd mailing list