kfree(pdent);
 }
 
-void ubifs_dump_node(const struct ubifs_info *c, const void *node)
+void ubifs_dump_node(const struct ubifs_info *c, const void *node, int node_len)
 {
-       int i, n;
+       int i, n, type, safe_len, max_node_len, min_node_len;
        union ubifs_key key;
        const struct ubifs_ch *ch = node;
        char key_buf[DBG_KEY_BUF_LEN];
                return;
        }
 
+       /* Skip dumping unknown type node */
+       type = ch->node_type;
+       if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) {
+               pr_err("node type %d was not recognized\n", type);
+               return;
+       }
+
        spin_lock(&dbg_lock);
        dump_ch(node);
 
-       switch (ch->node_type) {
+       if (c->ranges[type].max_len == 0) {
+               max_node_len = min_node_len = c->ranges[type].len;
+       } else {
+               max_node_len = c->ranges[type].max_len;
+               min_node_len = c->ranges[type].min_len;
+       }
+       safe_len = le32_to_cpu(ch->len);
+       safe_len = safe_len > 0 ? safe_len : 0;
+       safe_len = min3(safe_len, max_node_len, node_len);
+       if (safe_len < min_node_len) {
+               pr_err("node len(%d) is too short for %s, left %d bytes:\n",
+                      safe_len, dbg_ntype(type),
+                      safe_len > UBIFS_CH_SZ ?
+                      safe_len - (int)UBIFS_CH_SZ : 0);
+               if (safe_len > UBIFS_CH_SZ)
+                       print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 32, 1,
+                                      (void *)node + UBIFS_CH_SZ,
+                                      safe_len - UBIFS_CH_SZ, 0);
+               goto out_unlock;
+       }
+       if (safe_len != le32_to_cpu(ch->len))
+               pr_err("\ttruncated node length      %d\n", safe_len);
+
+       switch (type) {
        case UBIFS_PAD_NODE:
        {
                const struct ubifs_pad_node *pad = node;
                pr_err("\tnlen           %d\n", nlen);
                pr_err("\tname           ");
 
-               if (nlen > UBIFS_MAX_NLEN)
+               if (nlen > UBIFS_MAX_NLEN ||
+                   nlen > safe_len - UBIFS_DENT_NODE_SZ)
                        pr_err("(bad name length, not printing, bad or corrupted node)");
                else {
                        for (i = 0; i < nlen && dent->name[i]; i++)
        case UBIFS_DATA_NODE:
        {
                const struct ubifs_data_node *dn = node;
-               int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
 
                key_read(c, &dn->key, &key);
                pr_err("\tkey            %s\n",
                pr_err("\tsize           %u\n", le32_to_cpu(dn->size));
                pr_err("\tcompr_typ      %d\n",
                       (int)le16_to_cpu(dn->compr_type));
-               pr_err("\tdata size      %d\n", dlen);
-               pr_err("\tdata:\n");
+               pr_err("\tdata size      %u\n",
+                      le32_to_cpu(ch->len) - (unsigned int)UBIFS_DATA_NODE_SZ);
+               pr_err("\tdata (length = %d):\n",
+                      safe_len - (int)UBIFS_DATA_NODE_SZ);
                print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
-                              (void *)&dn->data, dlen, 0);
+                              (void *)&dn->data,
+                              safe_len - (int)UBIFS_DATA_NODE_SZ, 0);
                break;
        }
        case UBIFS_TRUN_NODE:
        case UBIFS_IDX_NODE:
        {
                const struct ubifs_idx_node *idx = node;
+               int max_child_cnt = (safe_len - UBIFS_IDX_NODE_SZ) /
+                                   (ubifs_idx_node_sz(c, 1) -
+                                   UBIFS_IDX_NODE_SZ);
 
-               n = le16_to_cpu(idx->child_cnt);
-               pr_err("\tchild_cnt      %d\n", n);
+               n = min_t(int, le16_to_cpu(idx->child_cnt), max_child_cnt);
+               pr_err("\tchild_cnt      %d\n", (int)le16_to_cpu(idx->child_cnt));
                pr_err("\tlevel          %d\n", (int)le16_to_cpu(idx->level));
                pr_err("\tBranches:\n");
 
                                le64_to_cpu(orph->cmt_no) & LLONG_MAX);
                pr_err("\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 = (safe_len - UBIFS_ORPH_NODE_SZ) >> 3;
                pr_err("\t%d orphan inode numbers:\n", n);
                for (i = 0; i < n; i++)
                        pr_err("\t  ino %llu\n",
                break;
        }
        default:
-               pr_err("node type %d was not recognized\n",
-                      (int)ch->node_type);
+               pr_err("node type %d was not recognized\n", type);
        }
+
+out_unlock:
        spin_unlock(&dbg_lock);
 }