Bounds check length of ubifs data node for hexdump
Due to corrupt ubifs meta data and a missing bounds check
dbg_dump_node() tried to dump a data buffer of length -1. The value -1
got coerced into a size_t. Since size_t is unsigned, print_hex_dump()
attempted to dump 0xFFFFFFFF bytes of data and eventually caused a page
fault.
Change-Id: I9d1fc1027d3c2118c0796f214c34ce93e8915a25
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 5047b57..6219f99 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -538,7 +538,14 @@
case UBIFS_DATA_NODE:
{
const struct ubifs_data_node *dn = node;
- int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
+ uint32_t dlen = le32_to_cpu(ch->len);
+
+ if (dlen > UBIFS_MAX_DATA_NODE_SZ)
+ dlen = UBIFS_MAX_DATA_NODE_SZ;
+ if (dlen < UBIFS_DATA_NODE_SZ)
+ dlen = 0;
+ else
+ dlen -= UBIFS_DATA_NODE_SZ;
key_read(c, &dn->key, &key);
printk(KERN_DEBUG "\tkey %s\n", DBGKEY(&key));
@@ -591,13 +598,21 @@
case UBIFS_ORPH_NODE:
{
const struct ubifs_orph_node *orph = node;
+ uint32_t dlen = le32_to_cpu(ch->len);
+
+ if (dlen > c->leb_size)
+ dlen = c->leb_size;
+ if (dlen < UBIFS_ORPH_NODE_SZ)
+ dlen = 0;
+ else
+ dlen -= UBIFS_ORPH_NODE_SZ;
printk(KERN_DEBUG "\tcommit number %llu\n",
(unsigned long long)
le64_to_cpu(orph->cmt_no) & LLONG_MAX);
printk(KERN_DEBUG "\tlast node flag %llu\n",
(unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63);
- n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3;
+ n = dlen >> 3;
printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n);
for (i = 0; i < n; i++)
printk(KERN_DEBUG "\t ino %llu\n",