AFFS oops.
It's a boring Sunday afternoon, so I decided to do some destruction testing on unusual filesystems. First on the list is AFFS.
I mounted a 900k AFFS floppy disk image via loopback, and ran fsx on it. It dies instantly, before fsx gets to do any of its usual fun.
Unable to handle kernel NULL pointer dereference at virtual address 00000008 c01de497 *pde = 00000000 Oops: 0000 CPU: 0 EIP: 0010:[<c01de497>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010282
eax: c01de488 ebx: 000006a0 ecx: cff63db8 edx: 00000000
esi: c12c5940 edi: cc511e8c ebp: cf983800 esp: cb1bfe98
ds: 0018 es: 0018 ss: 0018
Process a.out (pid: 10367, stackpage=cb1bf000)
Stack: 000006a0 c12c5940 cc511e8c cf983800 cc511e8c c01ded06 00000000 c12c5940
000006a0 000006a0 000186a0 00000000 cc511ddc 00000000 00000000 00000000
cc511ddc 00000000 000000cc c0126481 00000002 c01264e0 cc511ddc 00000048
Call Trace: [<c01ded06>] [<c0126481>] [<c01264e0>] [<c01480cb>] [<c01dce7f>]
[<c0148200>] [<c01344d9>] [<c0134777>] [<c0108743>]
Code: 8b 42 08 31 d2 8b 48 08 8b 74 24 1c 8b 46 18 a9 08 00 00 00 Quoted 1 line
Quoted 1 line
EIP;
c01de496<affs_commit_write_ofs+72/698> <=====
Trace; c01ded06 <affs_truncate+206/384>
Trace; c0126480 <do_swap_page+84/ec>
Trace; c01264e0 <do_swap_page+e4/ec>
Trace; c01480ca <notify_change+86/dc>
Trace; c01dce7e <affs_new_inode+66/1cc>
Trace; c0148200 <free_fd_array+8/4c>
Trace; c01344d8 <sys_truncate+148/180>
Trace; c0134776 <sys_truncate64+14a/184>
Trace; c0108742 <system_call+32/40>
Code; c01de496 <affs_commit_write_ofs+72/698>
00000000 <_EIP>:
Code; c01de496 <affs_commit_write_ofs+72/698> <=====
0: 8b 42 08 mov 0x8(%edx),%eax <=====
Code; c01de498 <affs_commit_write_ofs+74/698>
3: 31 d2 xor %edx,%edx
Code; c01de49a <affs_commit_write_ofs+76/698>
5: 8b 48 08 mov 0x8(%eax),%ecx
Code; c01de49e <affs_commit_write_ofs+7a/698>
8: 8b 74 24 1c mov 0x1c(%esp,1),%esi
Code; c01de4a2 <affs_commit_write_ofs+7e/698>
c: 8b 46 18 mov 0x18(%esi),%eax
Code; c01de4a4 <affs_commit_write_ofs+80/698>
f: a9 08 00 00 00 test $0x8,%eax
Signature · 2 lines
Dave Jones. http://www.codemonkey.org.uk SuSE Labs.
Quoted 4 lines · Dave Jones
Quoted 1 line
Quoted 1 line
EIP;
c01de496<affs_commit_write_ofs+72/698> <=====Trace;
c01ded06<affs_truncate+206/384>
Trace;c0126480<do_swap_page+84/ec>
Trace;c01264e0<do_swap_page+e4/ec>
This oops is pretty obvious:
res = mapping->a_ops->prepare_write(NULL, page, size, size);
if (!res)
res = mapping->a_ops->commit_write(NULL, page, size,size);
...and then affs_commit_write_ofs de-references arg1 first thing.
Signature · 4 lines
Jeff Garzik | Alternate titles for LOTR:
Building 1024 | Fast Times at Uruk-Hai
MandrakeSoft | The Took, the Elf, His Daughter and Her Lover
| Samwise Gamgee: International Hobbit of MysteryHi,
Quoted 2 lines · Dave Jones
It's a boring Sunday afternoon, so I decided to do some destruction testing on unusual filesystems. First on the list is AFFS.
Thanks for testing.
Quoted 2 lines
I mounted a 900k AFFS floppy disk image via loopback, and ran fsx on it. It dies instantly, before fsx gets to do any of its usual fun.
The patch below fixes everything I was able to find with fsx. Marcelo, could you please apply the patch?
Thanks.
bye, Roman
Index: fs/affs/Changes
===================================================================
RCS file: /usr/src/cvsroot/linux-2.4/fs/affs/Changes,v retrieving revision 1.1.1.4
affs/Changes +6 -0
@@ -28,6 +28,12 @@ Please direct bug reports to: [email protected] +Version 3.19 +------------ + +- sizeof changes from Kernel Janitor Project +- several bug fixes found with fsx + Version 3.18 ------------
Index: fs/affs/bitmap.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.4/fs/affs/bitmap.c,v retrieving revision 1.1.1.3
affs/bitmap.c +1 -1
@@ -292,7 +292,7 @@AFFS_SB ->s_bmap_bits = sb->s_blocksize *8 -32 ;AFFS_SB ->s_bmap_count = (AFFS_SB ->s_partition_size -AFFS_SB ->s_reserved +AFFS_SB ->s_bmap_bits -1 ) /AFFS_SB ->s_bmap_bits; - size =AFFS_SB ->s_bmap_count *sizeof (struct affs_bm_info ); + size =AFFS_SB ->s_bmap_count *sizeof (*bm); bm =AFFS_SB ->s_bitmap =kmalloc (size,GFP_KERNEL );if (!AFFS_SB ->s_bitmap) {printk (KERN_ERR "AFFS: Bitmap allocation failed\n" );
Index: fs/affs/file.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.4/fs/affs/file.c,v retrieving revision 1.1.1.10
affs/file.c +63 -25
236 lines not on this page · raw message
Index: fs/affs/inode.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.4/fs/affs/inode.c,v retrieving revision 1.1.1.10
affs/inode.c +2 -2
@@ -68,7 +68,7 @@ inode->i_size =0 ; inode->i_nlink =1 ; inode->i_mode =0 ; -memset (AFFS_INODE ,0 ,sizeof (struct affs_inode_info )); +memset (AFFS_INODE ,0 ,sizeof (*AFFS_INODE ));init_MUTEX (&AFFS_INODE ->i_link_lock);init_MUTEX (&AFFS_INODE ->i_ext_lock);AFFS_INODE ->i_extcnt =1 ;
@@ -318,7 +318,7 @@ inode->i_ino = block; inode->i_nlink =1 ; inode->i_mtime = inode->i_atime = inode->i_ctime =CURRENT_TIME ; -memset (AFFS_INODE ,0 ,sizeof (struct affs_inode_info )); +memset (AFFS_INODE ,0 ,sizeof (*AFFS_INODE ));AFFS_INODE ->i_extcnt =1 ;AFFS_INODE ->i_ext_last = ~1 ;init_MUTEX (&AFFS_INODE ->i_link_lock);
Index: fs/affs/super.c
===================================================================
RCS file: /usr/src/cvsroot/linux-2.4/fs/affs/super.c,v retrieving revision 1.1.1.7
affs/super.c +1 -1
@@ -240,7 +240,7 @@ sb->s_magic =AFFS_SUPER_MAGIC ; sb->s_op = &affs_sops; -memset (AFFS_SB ,0 ,sizeof (struct affs_sb_info )); +memset (AFFS_SB ,0 ,sizeof (*AFFS_SB ));init_MUTEX (&AFFS_SB ->s_bmlock); if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,