Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ubifs: Pass node length in all node dumping callers

Function ubifs_dump_node() has been modified to avoid memory oob
accessing while dumping node, node length (corresponding to the
size of allocated memory for node) should be passed into all node
dumping callers.

Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Zhihao Cheng and committed by
Richard Weinberger
a33e30a0 c8be0975

+54 -52
+2 -2
fs/ubifs/commit.c
··· 701 701 702 702 out_dump: 703 703 ubifs_err(c, "dumping index node (iip=%d)", i->iip); 704 - ubifs_dump_node(c, idx); 704 + ubifs_dump_node(c, idx, ubifs_idx_node_sz(c, c->fanout)); 705 705 list_del(&i->list); 706 706 kfree(i); 707 707 if (!list_empty(&list)) { 708 708 i = list_entry(list.prev, struct idx_node, list); 709 709 ubifs_err(c, "dumping parent index node"); 710 - ubifs_dump_node(c, &i->idx); 710 + ubifs_dump_node(c, &i->idx, ubifs_idx_node_sz(c, c->fanout)); 711 711 } 712 712 out_free: 713 713 while (!list_empty(&list)) {
+15 -15
fs/ubifs/debug.c
··· 871 871 cond_resched(); 872 872 pr_err("Dumping node at LEB %d:%d len %d\n", lnum, 873 873 snod->offs, snod->len); 874 - ubifs_dump_node(c, snod->node); 874 + ubifs_dump_node(c, snod->node, c->leb_size - snod->offs); 875 875 } 876 876 877 877 pr_err("(pid %d) finish dumping LEB %d\n", current->pid, lnum); ··· 1249 1249 ubifs_err(c, "but it should have key %s according to tnc", 1250 1250 dbg_snprintf_key(c, &zbr1->key, key_buf, 1251 1251 DBG_KEY_BUF_LEN)); 1252 - ubifs_dump_node(c, dent1); 1252 + ubifs_dump_node(c, dent1, UBIFS_MAX_DENT_NODE_SZ); 1253 1253 goto out_free; 1254 1254 } 1255 1255 ··· 1261 1261 ubifs_err(c, "but it should have key %s according to tnc", 1262 1262 dbg_snprintf_key(c, &zbr2->key, key_buf, 1263 1263 DBG_KEY_BUF_LEN)); 1264 - ubifs_dump_node(c, dent2); 1264 + ubifs_dump_node(c, dent2, UBIFS_MAX_DENT_NODE_SZ); 1265 1265 goto out_free; 1266 1266 } 1267 1267 ··· 1280 1280 dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN)); 1281 1281 1282 1282 ubifs_msg(c, "first node at %d:%d\n", zbr1->lnum, zbr1->offs); 1283 - ubifs_dump_node(c, dent1); 1283 + ubifs_dump_node(c, dent1, UBIFS_MAX_DENT_NODE_SZ); 1284 1284 ubifs_msg(c, "second node at %d:%d\n", zbr2->lnum, zbr2->offs); 1285 - ubifs_dump_node(c, dent2); 1285 + ubifs_dump_node(c, dent2, UBIFS_MAX_DENT_NODE_SZ); 1286 1286 1287 1287 out_free: 1288 1288 kfree(dent2); ··· 2147 2147 2148 2148 out_dump: 2149 2149 ubifs_msg(c, "dump of node at LEB %d:%d", zbr->lnum, zbr->offs); 2150 - ubifs_dump_node(c, node); 2150 + ubifs_dump_node(c, node, zbr->len); 2151 2151 out_free: 2152 2152 kfree(node); 2153 2153 return err; ··· 2280 2280 2281 2281 ubifs_msg(c, "dump of the inode %lu sitting in LEB %d:%d", 2282 2282 (unsigned long)fscki->inum, zbr->lnum, zbr->offs); 2283 - ubifs_dump_node(c, ino); 2283 + ubifs_dump_node(c, ino, zbr->len); 2284 2284 kfree(ino); 2285 2285 return -EINVAL; 2286 2286 } ··· 2351 2351 2352 2352 if (sa->type != UBIFS_DATA_NODE) { 2353 2353 ubifs_err(c, "bad node type %d", sa->type); 2354 - ubifs_dump_node(c, sa->node); 2354 + ubifs_dump_node(c, sa->node, c->leb_size - sa->offs); 2355 2355 return -EINVAL; 2356 2356 } 2357 2357 if (sb->type != UBIFS_DATA_NODE) { 2358 2358 ubifs_err(c, "bad node type %d", sb->type); 2359 - ubifs_dump_node(c, sb->node); 2359 + ubifs_dump_node(c, sb->node, c->leb_size - sb->offs); 2360 2360 return -EINVAL; 2361 2361 } 2362 2362 ··· 2387 2387 return 0; 2388 2388 2389 2389 error_dump: 2390 - ubifs_dump_node(c, sa->node); 2391 - ubifs_dump_node(c, sb->node); 2390 + ubifs_dump_node(c, sa->node, c->leb_size - sa->offs); 2391 + ubifs_dump_node(c, sb->node, c->leb_size - sb->offs); 2392 2392 return -EINVAL; 2393 2393 } 2394 2394 ··· 2419 2419 if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && 2420 2420 sa->type != UBIFS_XENT_NODE) { 2421 2421 ubifs_err(c, "bad node type %d", sa->type); 2422 - ubifs_dump_node(c, sa->node); 2422 + ubifs_dump_node(c, sa->node, c->leb_size - sa->offs); 2423 2423 return -EINVAL; 2424 2424 } 2425 2425 if (sb->type != UBIFS_INO_NODE && sb->type != UBIFS_DENT_NODE && 2426 2426 sb->type != UBIFS_XENT_NODE) { 2427 2427 ubifs_err(c, "bad node type %d", sb->type); 2428 - ubifs_dump_node(c, sb->node); 2428 + ubifs_dump_node(c, sb->node, c->leb_size - sb->offs); 2429 2429 return -EINVAL; 2430 2430 } 2431 2431 ··· 2475 2475 2476 2476 error_dump: 2477 2477 ubifs_msg(c, "dumping first node"); 2478 - ubifs_dump_node(c, sa->node); 2478 + ubifs_dump_node(c, sa->node, c->leb_size - sa->offs); 2479 2479 ubifs_msg(c, "dumping second node"); 2480 - ubifs_dump_node(c, sb->node); 2480 + ubifs_dump_node(c, sb->node, c->leb_size - sb->offs); 2481 2481 return -EINVAL; 2482 2482 } 2483 2483
+1 -1
fs/ubifs/file.c
··· 92 92 dump: 93 93 ubifs_err(c, "bad data node (block %u, inode %lu)", 94 94 block, inode->i_ino); 95 - ubifs_dump_node(c, dn); 95 + ubifs_dump_node(c, dn, UBIFS_MAX_DATA_NODE_SZ); 96 96 return -EINVAL; 97 97 } 98 98
+11 -12
fs/ubifs/io.c
··· 198 198 * ubifs_check_node - check node. 199 199 * @c: UBIFS file-system description object 200 200 * @buf: node to check 201 + * @len: node length 201 202 * @lnum: logical eraseblock number 202 203 * @offs: offset within the logical eraseblock 203 204 * @quiet: print no messages ··· 223 222 * This function returns zero in case of success and %-EUCLEAN in case of bad 224 223 * CRC or magic. 225 224 */ 226 - int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, 227 - int offs, int quiet, int must_chk_crc) 225 + int ubifs_check_node(const struct ubifs_info *c, const void *buf, int len, 226 + int lnum, int offs, int quiet, int must_chk_crc) 228 227 { 229 228 int err = -EINVAL, type, node_len; 230 229 uint32_t crc, node_crc, magic; ··· 282 281 out: 283 282 if (!quiet) { 284 283 ubifs_err(c, "bad node at LEB %d:%d", lnum, offs); 285 - ubifs_dump_node(c, buf); 284 + ubifs_dump_node(c, buf, len); 286 285 dump_stack(); 287 286 } 288 287 return err; ··· 719 718 int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) 720 719 { 721 720 struct ubifs_info *c = wbuf->c; 722 - int err, written, n, aligned_len = ALIGN(len, 8); 721 + int err, n, written = 0, aligned_len = ALIGN(len, 8); 723 722 724 723 dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len, 725 724 dbg_ntype(((struct ubifs_ch *)buf)->node_type), ··· 785 784 786 785 goto exit; 787 786 } 788 - 789 - written = 0; 790 787 791 788 if (wbuf->used) { 792 789 /* ··· 886 887 out: 887 888 ubifs_err(c, "cannot write %d bytes to LEB %d:%d, error %d", 888 889 len, wbuf->lnum, wbuf->offs, err); 889 - ubifs_dump_node(c, buf); 890 + ubifs_dump_node(c, buf, written + len); 890 891 dump_stack(); 891 892 ubifs_dump_leb(c, wbuf->lnum); 892 893 return err; ··· 929 930 930 931 err = ubifs_leb_write(c, lnum, buf, offs, buf_len); 931 932 if (err) 932 - ubifs_dump_node(c, buf); 933 + ubifs_dump_node(c, buf, len); 933 934 934 935 return err; 935 936 } ··· 1012 1013 goto out; 1013 1014 } 1014 1015 1015 - err = ubifs_check_node(c, buf, lnum, offs, 0, 0); 1016 + err = ubifs_check_node(c, buf, len, lnum, offs, 0, 0); 1016 1017 if (err) { 1017 1018 ubifs_err(c, "expected node type %d", type); 1018 1019 return err; ··· 1028 1029 1029 1030 out: 1030 1031 ubifs_err(c, "bad node at LEB %d:%d", lnum, offs); 1031 - ubifs_dump_node(c, buf); 1032 + ubifs_dump_node(c, buf, len); 1032 1033 dump_stack(); 1033 1034 return -EINVAL; 1034 1035 } ··· 1068 1069 goto out; 1069 1070 } 1070 1071 1071 - err = ubifs_check_node(c, buf, lnum, offs, 0, 0); 1072 + err = ubifs_check_node(c, buf, len, lnum, offs, 0, 0); 1072 1073 if (err) { 1073 1074 ubifs_errc(c, "expected node type %d", type); 1074 1075 return err; ··· 1086 1087 ubifs_errc(c, "bad node at LEB %d:%d, LEB mapping status %d", lnum, 1087 1088 offs, ubi_is_mapped(c->ubi, lnum)); 1088 1089 if (!c->probing) { 1089 - ubifs_dump_node(c, buf); 1090 + ubifs_dump_node(c, buf, len); 1090 1091 dump_stack(); 1091 1092 } 1092 1093 return -EINVAL;
+2 -1
fs/ubifs/journal.c
··· 1559 1559 if (dn_len <= 0 || dn_len > UBIFS_BLOCK_SIZE) { 1560 1560 ubifs_err(c, "bad data node (block %u, inode %lu)", 1561 1561 blk, inode->i_ino); 1562 - ubifs_dump_node(c, dn); 1562 + ubifs_dump_node(c, dn, sz - UBIFS_INO_NODE_SZ - 1563 + UBIFS_TRUN_NODE_SZ); 1563 1564 goto out_free; 1564 1565 } 1565 1566
+2 -2
fs/ubifs/master.c
··· 314 314 315 315 out: 316 316 ubifs_err(c, "bad master node at offset %d error %d", c->mst_offs, err); 317 - ubifs_dump_node(c, c->mst_node); 317 + ubifs_dump_node(c, c->mst_node, c->mst_node_alsz); 318 318 return -EINVAL; 319 319 } 320 320 ··· 392 392 if (c->leb_cnt < old_leb_cnt || 393 393 c->leb_cnt < UBIFS_MIN_LEB_CNT) { 394 394 ubifs_err(c, "bad leb_cnt on master node"); 395 - ubifs_dump_node(c, c->mst_node); 395 + ubifs_dump_node(c, c->mst_node, c->mst_node_alsz); 396 396 return -EINVAL; 397 397 } 398 398
+4 -2
fs/ubifs/orphan.c
··· 646 646 if (snod->type != UBIFS_ORPH_NODE) { 647 647 ubifs_err(c, "invalid node type %d in orphan area at %d:%d", 648 648 snod->type, sleb->lnum, snod->offs); 649 - ubifs_dump_node(c, snod->node); 649 + ubifs_dump_node(c, snod->node, 650 + c->leb_size - snod->offs); 650 651 err = -EINVAL; 651 652 goto out_free; 652 653 } ··· 675 674 if (!first) { 676 675 ubifs_err(c, "out of order commit number %llu in orphan node at %d:%d", 677 676 cmt_no, sleb->lnum, snod->offs); 678 - ubifs_dump_node(c, snod->node); 677 + ubifs_dump_node(c, snod->node, 678 + c->leb_size - snod->offs); 679 679 err = -EINVAL; 680 680 goto out_free; 681 681 }
+3 -3
fs/ubifs/recovery.c
··· 352 352 ubifs_err(c, "failed to recover master node"); 353 353 if (mst1) { 354 354 ubifs_err(c, "dumping first master node"); 355 - ubifs_dump_node(c, mst1); 355 + ubifs_dump_node(c, mst1, c->leb_size - ((void *)mst1 - buf1)); 356 356 } 357 357 if (mst2) { 358 358 ubifs_err(c, "dumping second master node"); 359 - ubifs_dump_node(c, mst2); 359 + ubifs_dump_node(c, mst2, c->leb_size - ((void *)mst2 - buf2)); 360 360 } 361 361 vfree(buf2); 362 362 vfree(buf1); ··· 469 469 * The area after the common header size is not empty, so the common 470 470 * header must be intact. Check it. 471 471 */ 472 - if (ubifs_check_node(c, buf, lnum, offs, 1, 0) != -EUCLEAN) { 472 + if (ubifs_check_node(c, buf, len, lnum, offs, 1, 0) != -EUCLEAN) { 473 473 dbg_rcvry("unexpected bad common header at %d:%d", lnum, offs); 474 474 return 0; 475 475 }
+2 -2
fs/ubifs/replay.c
··· 827 827 828 828 out_dump: 829 829 ubifs_err(c, "bad node is at LEB %d:%d", lnum, snod->offs); 830 - ubifs_dump_node(c, snod->node); 830 + ubifs_dump_node(c, snod->node, c->leb_size - snod->offs); 831 831 ubifs_scan_destroy(sleb); 832 832 return -EINVAL; 833 833 } ··· 1123 1123 out_dump: 1124 1124 ubifs_err(c, "log error detected while replaying the log at LEB %d:%d", 1125 1125 lnum, offs + snod->offs); 1126 - ubifs_dump_node(c, snod->node); 1126 + ubifs_dump_node(c, snod->node, c->leb_size - snod->offs); 1127 1127 ubifs_scan_destroy(sleb); 1128 1128 return -EINVAL; 1129 1129 }
+1 -1
fs/ubifs/sb.c
··· 503 503 504 504 failed: 505 505 ubifs_err(c, "bad superblock, error %d", err); 506 - ubifs_dump_node(c, sup); 506 + ubifs_dump_node(c, sup, ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size)); 507 507 return -EINVAL; 508 508 } 509 509
+2 -2
fs/ubifs/scan.c
··· 76 76 dbg_scan("scanning %s at LEB %d:%d", 77 77 dbg_ntype(ch->node_type), lnum, offs); 78 78 79 - if (ubifs_check_node(c, buf, lnum, offs, quiet, 1)) 79 + if (ubifs_check_node(c, buf, len, lnum, offs, quiet, 1)) 80 80 return SCANNED_A_CORRUPT_NODE; 81 81 82 82 if (ch->node_type == UBIFS_PAD_NODE) { ··· 90 90 if (!quiet) { 91 91 ubifs_err(c, "bad pad node at LEB %d:%d", 92 92 lnum, offs); 93 - ubifs_dump_node(c, pad); 93 + ubifs_dump_node(c, pad, len); 94 94 } 95 95 return SCANNED_A_BAD_PAD_NODE; 96 96 }
+1 -1
fs/ubifs/super.c
··· 253 253 254 254 out_invalid: 255 255 ubifs_err(c, "inode %lu validation failed, error %d", inode->i_ino, err); 256 - ubifs_dump_node(c, ino); 256 + ubifs_dump_node(c, ino, UBIFS_MAX_INO_NODE_SZ); 257 257 ubifs_dump_inode(c, inode); 258 258 err = -EINVAL; 259 259 out_ino:
+4 -4
fs/ubifs/tnc.c
··· 316 316 err = ubifs_validate_entry(c, dent); 317 317 if (err) { 318 318 dump_stack(); 319 - ubifs_dump_node(c, dent); 319 + ubifs_dump_node(c, dent, zbr->len); 320 320 return err; 321 321 } 322 322 ··· 349 349 err = ubifs_validate_entry(c, node); 350 350 if (err) { 351 351 dump_stack(); 352 - ubifs_dump_node(c, node); 352 + ubifs_dump_node(c, node, zbr->len); 353 353 return err; 354 354 } 355 355 ··· 1699 1699 goto out_err; 1700 1700 } 1701 1701 1702 - err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0); 1702 + err = ubifs_check_node(c, buf, zbr->len, zbr->lnum, zbr->offs, 0, 0); 1703 1703 if (err) { 1704 1704 ubifs_err(c, "expected node type %d", UBIFS_DATA_NODE); 1705 1705 goto out; ··· 1733 1733 err = -EINVAL; 1734 1734 out: 1735 1735 ubifs_err(c, "bad node at LEB %d:%d", zbr->lnum, zbr->offs); 1736 - ubifs_dump_node(c, buf); 1736 + ubifs_dump_node(c, buf, zbr->len); 1737 1737 dump_stack(); 1738 1738 return err; 1739 1739 }
+2 -2
fs/ubifs/tnc_misc.c
··· 390 390 391 391 out_dump: 392 392 ubifs_err(c, "bad indexing node at LEB %d:%d, error %d", lnum, offs, err); 393 - ubifs_dump_node(c, idx); 393 + ubifs_dump_node(c, idx, c->max_idx_node_sz); 394 394 kfree(idx); 395 395 return -EINVAL; 396 396 } ··· 488 488 zbr->lnum, zbr->offs); 489 489 dbg_tnck(key, "looked for key "); 490 490 dbg_tnck(&key1, "but found node's key "); 491 - ubifs_dump_node(c, node); 491 + ubifs_dump_node(c, node, zbr->len); 492 492 return -EINVAL; 493 493 } 494 494
+2 -2
fs/ubifs/ubifs.h
··· 1719 1719 int offs); 1720 1720 int ubifs_write_node_hmac(struct ubifs_info *c, void *buf, int len, int lnum, 1721 1721 int offs, int hmac_offs); 1722 - int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, 1723 - int offs, int quiet, int must_chk_crc); 1722 + int ubifs_check_node(const struct ubifs_info *c, const void *buf, int len, 1723 + int lnum, int offs, int quiet, int must_chk_crc); 1724 1724 void ubifs_init_node(struct ubifs_info *c, void *buf, int len, int pad); 1725 1725 void ubifs_crc_node(struct ubifs_info *c, void *buf, int len); 1726 1726 void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);