ubifs_dump_node must bounds check ubifs_ch->len
Daniel Mentz
danielmentz at google.com
Thu Aug 28 15:37:52 PDT 2014
I believe that ubifs_dump_node() must bounds check ch->len in the
UBIFS_DATA_NODE case. It currently does not which resulted in a crash
on a system. See below.
This is the source code as it stands today:
int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
(void *)&dn->data, dlen, 0);
For some reason, ch->len was 47. UBIFS_DATA_NODE_SZ appears to be 48,
so dlen got assigned -1 which is then coerced into a size_t. Since
size_t is unsigned, it effectively passes 0xFFFFFFFF to
print_hex_dump().
[ 23.873556] UBIFS: recovery needed
[ 25.530459] UBIFS error (pid 772): ubifs_check_node: bad node length 47
[ 25.537102] UBIFS error (pid 772): ubifs_check_node: bad node at
LEB 246:621328
[ 25.547138] magic 0x6101831
[ 25.550833] crc 0xdbc28925
[ 25.554594] node_type 1 (data node)
[ 25.558629] group_type 0 (no node group)
[ 25.562998] sqnum 736111
[ 25.566409] len 47
[ 25.569485] key (7202, data, 816)
[ 25.573854] size 4096
[ 25.577091] compr_typ 1
[ 25.580089] data size -1
[ 25.583159] data:
[ 25.585181] 00000000: 31 18 10 06 42 3c b0 0d 70 3b 0b 00 00 00 00
00 30 10 00 00 01 00 00 00 22 1c 00 00 31 03 00 20
This is the backtrace from a different crash caused by the same bug:
[ 166.638230] Unable to handle kernel paging request at virtual
address c52fd000
[ 166.645490] pgd = bdaa4000
[ 166.648212] [c52fd000] *pgd=3db9a811, *pte=00000000, *ppte=00000000
[ 166.654563] Internal error: Oops: 7 [#1] PREEMPT SMP
[ 166.659544] Modules linked in: pfe(O)
[ 166.663245] CPU: 0 Tainted: G O (3.2.26 #4)
[ 166.668671] PC is at hex_dump_to_buffer+0x14c/0x1f0
[ 166.673566] LR is at hex_dump_to_buffer+0x45/0x1f0
[ 166.678374] pc : [<8417e410>] lr : [<8417e309>] psr: 20000133
[ 166.678378] sp : bdef7bb8 ip : 842dd804 fp : 00000000
[ 166.689896] r10: 00000020 r9 : c52fd000 r8 : 00000020
[ 166.695137] r7 : 00000020 r6 : 00000083 r5 : bdef7c1c r4 : 00000000
[ 166.701684] r3 : bdef7c1f r2 : 00000003 r1 : 00000000 r0 : 00000020
[ 166.708234] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA Thumb
Segment user
[ 166.715566] Control: 50c53c7d Table: 3daa404a DAC: 00000015
[ 166.721329] Process mount (pid: 772, stack limit = 0xbdef62f0)
<snip>
[ 167.018746] [<8417e410>] (hex_dump_to_buffer+0x14c/0x1f0) from
[<8417e513>] (print_hex_dump+0x5f/0xb8)
[ 167.028100] [<8417e513>] (print_hex_dump+0x5f/0xb8) from
[<8414e3cf>] (dbg_dump_node+0xdf3/0x1218)
[ 167.037107] [<8414e3cf>] (dbg_dump_node+0xdf3/0x1218) from
[<84136a41>] (ubifs_check_node+0x1dd/0x214)
[ 167.046451] [<84136a41>] (ubifs_check_node+0x1dd/0x214) from
[<8413bd13>] (ubifs_scan_a_node+0x7f/0x158)
[ 167.055965] [<8413bd13>] (ubifs_scan_a_node+0x7f/0x158) from
[<8413c0cd>] (ubifs_scan+0x41/0x22c)
[ 167.064870] [<8413c0cd>] (ubifs_scan+0x41/0x22c) from [<8413cbf7>]
(ubifs_replay_journal+0x72f/0x1200)
[ 167.074211] [<8413cbf7>] (ubifs_replay_journal+0x72f/0x1200) from
[<8413411f>] (ubifs_mount+0xe97/0x18b8)
[ 167.083821] [<8413411f>] (ubifs_mount+0xe97/0x18b8) from
[<84099fef>] (mount_fs+0xb/0x78)
[ 167.092040] [<84099fef>] (mount_fs+0xb/0x78) from [<840a9dc7>]
(vfs_kern_mount+0x37/0x60)
[ 167.100251] [<840a9dc7>] (vfs_kern_mount+0x37/0x60) from
[<840aa09d>] (do_kern_mount+0x21/0x88)
[ 167.108983] [<840aa09d>] (do_kern_mount+0x21/0x88) from
[<840ab1d5>] (do_mount+0x481/0x4d0)
[ 167.117366] [<840ab1d5>] (do_mount+0x481/0x4d0) from [<840ab58f>]
(sys_mount+0x5b/0x84)
[ 167.125408] [<840ab58f>] (sys_mount+0x5b/0x84) from [<8400cdc1>]
(ret_fast_syscall+0x1/0x44)
[ 167.133878] Code: 0b8b f10b 0b02 e01d (f819) 0001
More information about the linux-mtd
mailing list