floppy oops in 2.1.56 - "if (!filp) use filp->d_entry"

David Woodhouse (D.W.Woodhouse@nortel.co.uk)
Tue, 23 Sep 1997 10:02:16 +0100


Upon unmounting. I thought this had been reported before, but it was only done
in 2.1.56, so it must have been a different one.

Unable to handle kernel NULL pointer dereference at virtual address 00000008
current->tss.cr3 = 03da0000, (r3 = 03da0000
*pde = 00000000
Oops: 0000
CPU: 0
EIP: 0010:[<c483c099>]
EFLAGS: 00010246
eax: c3790000 ebx: 00000000 ecx: 00000000 edx: c3790000
esi: 08040200 edi: 00000000 ebp: c37905b8 esp: c37e9f78
ds: 0018 es: 0018 ss: 0018
Process umount (pid: 517, process nr: 4, stackpage=c37e9000)
Stack: c37905b8 08040200 00000000 c0122c9e c37905b8 00000000 00000200 c0126034
c37905b8 00000000 08040200 c36a32c0 bffffc64 c01260eb 00000200 c37e8000
0804ea49 0804b75b c010924a 0804ea48 00000007 0804ea48 0804ea49 0804b75b
Call Trace: [<c0122c9e>] [<c0126034>] [<c01260eb>] [<c010924a>]
Code: 8b 41 08 50 51 e8 29 b2 8e fb 83 c4 08 be 38 02 84 c4 8d 04
Using `sysmap+floppy' to map addresses to symbols.

>>EIP: c483c099 <floppy_release+2d/94>
Trace: c0122c9e <blkdev_release+22/2c>
Trace: c0126034 <umount_dev+60/7c>
Trace: c01260eb <sys_umount+9b/a8>
Trace: c010924a <system_call+3a/40>

Code: c483c099 <floppy_release+2d/94>
Code: c483c099 <floppy_release+2d/94> 8b 41 08 movl 0x8(%ecx),%eax
Code: c483c09c <floppy_release+30/94> 50 pushl %eax
Code: c483c09d <floppy_release+31/94> 51 pushl %ecx
Code: c483c09e <floppy_release+32/94> e8 29 b2 8e fb call fb8eb233
<_EIP+fb8eb233>
Code: c483c0a9 <floppy_release+3d/94> 83 c4 08 addl $0x8,%esp
Code: c483c0ac <floppy_release+40/94> be 38 02 84 c4 movl $0xc4840238,%esi
Code: c483c0b1 <floppy_release+45/94> 8d 04 00 leal
(%eax,%eax,1),%eax
Code: c483c0ba <floppy_release+4e/94> 90 nop
Code: c483c0bb <floppy_release+4f/94> 90 nop
Code: c483c0bc <floppy_release+50/94> 90 nop

Dump of assembler code for function floppy_release:
0x6024 <floppy_release>: pushl %edi
0x6025 <floppy_release+1>: pushl %esi
0x6026 <floppy_release+2>: pushl %ebx
0x6027 <floppy_release+3>: movl 0x10(%esp,1),%eax
0x602b <floppy_release+7>: movl 0x14(%esp,1),%ecx
0x602f <floppy_release+11>: movw 0x20(%eax),%ax
0x6033 <floppy_release+15>: movl %eax,%edx
0x6035 <floppy_release+17>: andw $0x3,%dx
0x6039 <floppy_release+21>: andw $0x80,%ax
0x603d <floppy_release+25>: shrw $0x5,%ax
0x6041 <floppy_release+29>: orw %ax,%dx
0x6044 <floppy_release+32>: movzwl %dx,%ebx
0x6047 <floppy_release+35>: testl %ecx,%ecx
0x6049 <floppy_release+37>: je 0x6051 <floppy_release+45>
0x604b <floppy_release+39>: testb $0x12,0x10(%ecx)
0x604f <floppy_release+43>: je 0x605e <floppy_release+58>
0x6051 <floppy_release+45>: movl 0x8(%ecx),%eax <--- oops
here
0x6054 <floppy_release+48>: pushl %eax
0x6055 <floppy_release+49>: pushl %ecx
0x6056 <floppy_release+50>: call 0x6057 <floppy_release+51>
0x605b <floppy_release+55>: addl $0x8,%esp
0x605e <floppy_release+58>: movl $0x2d4,%esi

Hmmm.

Code goes:
if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
/* if the file is mounted OR (writable now AND writable at
* open time) Linus: Does this cover all cases? */
block_fsync(filp, filp->f_dentry);

I would suggest that constructs such as "if (!filp) do something with filp->
f_dentry" are definitely a BadThing (TM acknowledged) and should be avoided if
at all possible.

Search-and-replace with lint, anyone?

Happy Hacking.

-- 
David Woodhouse,	CB3 9AN		http://dwmw2.robinson.cam.ac.uk/
	dwmw2@cam.ac.uk 		 Tel: 0976 658355        
      ( D.W.Woodhouse@nortel.co.uk	 Tel: 01279 402332 )

(Use the former; I'm going back to College next week.)