MOKB-02-11-2006

Bug details
Title: Linux 2.6.x squashfs double free
Description: The squashfs module of the Linux kernel (2.6.x) fails to properly handle corrupted fs structures, leading to a denial of service and possible data corruption condition. A specially crafted squashfs image will cause the kernel to double free a buffer when a read operation is performed on the corrupted filesystem.
Author/Contributor:
References:
Proof of concept or exploit: The following filesystem image can be used to reproduce the bug: MOKB-02-11-2006.img.gz
Use a loopback device to mount it: gunzip MOKB-02-11-2006.img.gz && mount MOKB-02-11-2006.img /mnt/foo -t squashfs -o loop
Debugging information:

The bug has been found using fsfuzzer on a fully patched, up to date Fedora Core 5 installation. A read operation is necessary to trigger the bug. The architecture used to conduct the tests is IA32/x86, running with SMP support enabled in the kernel.

Under certain conditions, different bugs may be triggered by the same proof of concept. When the process trying to perform the read operation halts, any attempt to send a signal to that process will also halt the process sending the signal itself (ex. kill, killall). Finally, the system may hard lock (no debugging output for this right now, but it can be noticed easily as input will no longer work).

[root@fedora ~]# uname -a
Linux fedora 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:37:32 EDT 2006 i686 i686 i386 GNU/Linux
				

The following output can be seen in the system log and kernel messages buffer;

VFS: brelse: Trying to free free buffer
BUG: warning at fs/buffer.c:1277/__brelse() (Tainted: P     )
 [] dump_trace+0x69/0x1af
 [] show_trace_log_lvl+0x18/0x2c
 [] show_trace+0xf/0x11
 [] dump_stack+0x15/0x17
 [] squashfs_read_data+0x523/0x555 [squashfs]
 [] squashfs_get_cached_block+0x1e2/0x3c0 [squashfs]
 [] squashfs_iget+0x231/0x17e8 [squashfs]
 [] squashfs_fill_super+0xa74/0xb3a [squashfs]
 [] get_sb_bdev+0xce/0x11c
 [] squashfs_get_sb+0x20/0x25 [squashfs]
 [] vfs_kern_mount+0x83/0xf6
 [] do_kern_mount+0x2d/0x3e
 [] do_mount+0x5fa/0x66d
 [] sys_mount+0x77/0xae
 [] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
 =======================
VFS: brelse: Trying to free free buffer
BUG: warning at fs/buffer.c:1277/__brelse() (Tainted: P     )
 [] dump_trace+0x69/0x1af
 [] show_trace_log_lvl+0x18/0x2c
 [] show_trace+0xf/0x11
 [] dump_stack+0x15/0x17
 [] squashfs_read_data+0x523/0x555 [squashfs]
 [] squashfs_get_cached_block+0x1e2/0x3c0 [squashfs]
 [] squashfs_iget+0x231/0x17e8 [squashfs]
 [] squashfs_fill_super+0xa74/0xb3a [squashfs]
 [] get_sb_bdev+0xce/0x11c
 [] squashfs_get_sb+0x20/0x25 [squashfs]
 [] vfs_kern_mount+0x83/0xf6
 [] do_kern_mount+0x2d/0x3e
 [] do_mount+0x5fa/0x66d
 [] sys_mount+0x77/0xae
 [] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
 =======================
VFS: brelse: Trying to free free buffer
BUG: warning at fs/buffer.c:1277/__brelse() (Tainted: P     )
 [] dump_trace+0x69/0x1af
 [] show_trace_log_lvl+0x18/0x2c
 [] show_trace+0xf/0x11
 [] dump_stack+0x15/0x17
 [] squashfs_read_data+0x523/0x555 [squashfs]
 [] squashfs_get_cached_block+0x1e2/0x3c0 [squashfs]
 [] squashfs_iget+0x231/0x17e8 [squashfs]
 [] squashfs_fill_super+0xa74/0xb3a [squashfs]
 [] get_sb_bdev+0xce/0x11c
 [] squashfs_get_sb+0x20/0x25 [squashfs]
 [] vfs_kern_mount+0x83/0xf6
 [] do_kern_mount+0x2d/0x3e
 [] do_mount+0x5fa/0x66d
 [] sys_mount+0x77/0xae
 [] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
 =======================
VFS: brelse: Trying to free free buffer
BUG: warning at fs/buffer.c:1277/__brelse() (Tainted: P     )
 [] dump_trace+0x69/0x1af
 [] show_trace_log_lvl+0x18/0x2c
 [] show_trace+0xf/0x11
 [] dump_stack+0x15/0x17
 [] squashfs_read_data+0x523/0x555 [squashfs]
 [] squashfs_get_cached_block+0x1e2/0x3c0 [squashfs]
 [] squashfs_iget+0x231/0x17e8 [squashfs]
 [] squashfs_fill_super+0xa74/0xb3a [squashfs]
 [] get_sb_bdev+0xce/0x11c
 [] squashfs_get_sb+0x20/0x25 [squashfs]
 [] vfs_kern_mount+0x83/0xf6
 [] do_kern_mount+0x2d/0x3e
 [] do_mount+0x5fa/0x66d
 [] sys_mount+0x77/0xae
 [] syscall_call+0x7/0xb
DWARF2 unwinder stuck at syscall_call+0x7/0xb
Leftover inexact backtrace:
 =======================