omfs: fix potential oops when directory size is corrupted
Testing with a modified fsfuzzer reveals a couple of locations in omfs
where filesystem variables are ultimately used as loop counters with
insufficient sanity checking. In this case, dir->i_size is used to
compute the number of buckets in the directory hash. If too large,
readdir will overrun a buffer.
Since it's an invariant that dir->i_size is equal to the sysblock
size, and we already sanity check that, just use that value instead.
This fixes the following oops:
BUG: unable to handle kernel paging request at
c978e004
IP: [<
c032298e>] omfs_readdir+0x18e/0x32f
Oops: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
Modules linked in:
Pid: 4796, comm: ls Not tainted (2.6.27-rc2 #12)
EIP: 0060:[<
c032298e>] EFLAGS:
00010287 CPU: 0
EIP is at omfs_readdir+0x18e/0x32f
EAX:
c978d000 EBX:
00000000 ECX:
cbfcfaf8 EDX:
cb2cf100
ESI:
00001000 EDI:
00000800 EBP:
cb2d3f68 ESP:
cb2d3f0c
DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process ls (pid: 4796, ti=
cb2d3000 task=
cb175f40 task.ti=
cb2d3000)
Stack:
00000002 00000000 00000000 c018a820 cb2d3f94 cb2cf100 cbfb0000 ffffff10
cbfb3b80 cbfcfaf8 000001c9 00000a09 00000000 00000000 00000000 cbfcfbc8
c9697000 cbfb3b80 22222222 00001000 c08e6cd0 cb2cf100 cbfb3b80 cb2d3f88
Call Trace:
[<
c018a820>] ? filldir64+0x0/0xcd
[<
c018a9f2>] ? vfs_readdir+0x56/0x82
[<
c018a820>] ? filldir64+0x0/0xcd
[<
c018aa7c>] ? sys_getdents64+0x5e/0xa0
[<
c01038bd>] ? sysenter_do_call+0x12/0x31
=======================
Code: 00 89 f0 89 f3 0f ac f8 14 81 e3 ff ff 0f 00 48 8d
14 c5 b8 01 00 00 89 45 cc 89 55 f0 e9 8c 01 00 00 8b 4d c8 8b 75 f0 8b
41 18 <8b> 54 30 04 8b 04 30 31 f6 89 5d dc 89 d1 8b 55 b8 0f c8 0f c9
Reported-by: Eric Sesterhenn <snakebyte@gmx.de>
Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>