I'm getting a kernel oops indicating a null pointer dereference in
xfs_alloc_lookup(). The symptoms are similar in many respects to those
indicated at
http://lists.insecure.org/lists/linux-kernel/2003/Sep/6937.html. There
doesn't seem to be any follow-up to that article, however.
What seems to be happening is xfs_alloc_lookup() calls
xfs_btree_read_bufs() to get a new buffer. xfs_btree_read_bufs() returns a
null bp, but doesn't return an error. xfs_alloc_lookup(), doesn't check to
see if bp is null, attempts to dereference it and oopses.
in xfs_alloc_btree.c, xfs_alloc_lookup()
...
/*
* If the old buffer at this level is for a different block,
* throw it away, otherwise just use it.
*/
bp = cur->bc_bufs[level];
if (bp && XFS_BUF_ADDR(bp) != d)
bp = (xfs_buf_t *)0;
if (!bp) {
/*
* Need to get a new buffer. Read it, then
* set it in the cursor, releasing the old one.
*/
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, agno,
agbno, 0, &bp, XFS_ALLOC_BTREE_REF)))
return error;
xfs_btree_setbuf(cur, level, bp);
/*
* Point to the btree block, now that we have the buffer
*/
OOPS HAPPENS HERE ==> block = XFS_BUF_TO_ALLOC_BLOCK(bp);
if ((error = xfs_btree_check_sblock(cur, block, level,
bp)))
return error;
} else
block = XFS_BUF_TO_ALLOC_BLOCK(bp);
...
The oops occurred on Linux i386 kernel 2.4.22 and "SGI XFS snapshot
2.4.22-2003-09-03_04:09_UTC with ACLs, no debug enabled". The code problem
is quite evident in the current CVS, however.
Does anyone have any comments/ideas on this? Are there any obvious
work-arounds? Is the problem simply the lack of null-checking in
xfs_alloc_lookup(), or should xfs_btree_read_bufs() not have handed back
null in the first place? If it is simply the former, then I suspect there
are several other places in the code which will need null-checking.
The output of ksymoops follows.
Jim Minter <jim@xxxxxxxxxxxxxxxxxx>
Nov 16 20:05:12 localhost kernel: Unable to handle kernel NULL pointer
dereference at virtual address 0000005c
Nov 16 20:05:12 localhost kernel: c01eb539
Nov 16 20:05:12 localhost kernel: *pde = 00000000
Nov 16 20:05:12 localhost kernel: Oops: 0000
Nov 16 20:05:12 localhost kernel: CPU: 3
Nov 16 20:05:56 localhost kernel: EIP: 0010:[<c01eb539>] Not tainted
Nov 16 20:05:56 localhost kernel: EFLAGS: 00010286
Nov 16 20:05:56 localhost kernel: eax: 00000000 ebx: 00000000 ecx:
f7ba372c edx: c86eeeec
Nov 16 20:05:56 localhost kernel: esi: 059627d8 edi: 0002c4fb ebp:
00000000 esp: f7bd3940
Nov 16 20:05:56 localhost kernel: ds: 0018 es: 0018 ss: 0018
Nov 16 20:05:56 localhost kernel: Process kswapd (pid: 7, stackpage=f7bd3000)
Nov 16 20:06:55 localhost kernel: Stack: c86eeeec 00000000 00000000 0002c4fb
00000000 f7bd3980 00000002 c0255379
Nov 16 20:06:55 localhost kernel: c6262010 00000000 0000000b f7045400
0000000b 000027a5 0002c4fb f7ba3544
Nov 16 20:06:55 localhost kernel: 00000000 00000000 f7bd3b0c c86eef70
f7bd3a00 c01e71d8 c86eeeec 00000001
Nov 16 20:06:55 localhost kernel: Call Trace: [<c0255379>] [<c01e71d8>]
[<c03a0780>] [<c01e6dbe>] [<c01e9a5c>] [<c01f8897>] [<c03cdb58>] [
<c03cdeb5>] [<c0203b2f>] [<c01fd23f>] [<c0203b2f>] [<c01fac38>]
[<c03b3940>] [<c03a0780>] [<c03b3940>] [<c01fad67>] [<c0229852>] [<c024
fd05>] [<c022147e>] [<c024f028>] [<c024a852>] [<c024b6e8>] [<c0128d9a>]
[<c0118085>] [<c024be3e>] [<c0148102>] [<c013bcb1>] [<c013bef3>
Nov 16 20:06:55 localhost kernel: Code: 8b 70 5c 89 44 24 0c 89 14 24 89 6c 24
08 89 74 24 04 e8 10
>>EIP; c01eb539 <xfs_alloc_lookup+119/3c0> <=====
>>ecx; f7ba372c <END_OF_CODE+37608ab8/????>
>>edx; c86eeeec <END_OF_CODE+8154278/????>
>>esi; 059627d8 Before first symbol
>>edi; 0002c4fb Before first symbol
>>esp; f7bd3940 <END_OF_CODE+37638ccc/????>
Trace; c0255379 <kmem_zone_zalloc+f9/130>
Trace; c01e71d8 <xfs_alloc_ag_vextent_near+1e8/cf0>
Trace; c03a0780 <nf_hook_slow+100/1d0>
Trace; c01e6dbe <xfs_alloc_ag_vextent+12e/140>
Trace; c01e9a5c <xfs_alloc_vextent+2fc/3b0>
Trace; c01f8897 <xfs_bmap_alloc+897/1390>
Trace; c03cdb58 <tcp_create_openreq_child+2f8/490>
Trace; c03cdeb5 <tcp_check_req+1c5/480>
Trace; c0203b2f <xfs_bmbt_get_state+2f/40>
Trace; c01fd23f <xfs_bmapi+e7f/1540>
Trace; c0203b2f <xfs_bmbt_get_state+2f/40>
Trace; c01fac38 <xfs_bmap_do_search_extents+b8/3e0>
Trace; c03b3940 <ip_queue_xmit2+0/24a>
Trace; c03a0780 <nf_hook_slow+100/1d0>
Trace; c03b3940 <ip_queue_xmit2+0/24a>
Trace; c01fad67 <xfs_bmap_do_search_extents+1e7/3e0>
Trace; c0229852 <xfs_log_reserve+c2/d0>
Code; c01eb539 <xfs_alloc_lookup+119/3c0>
00000000 <_EIP>:
Code; c01eb539 <xfs_alloc_lookup+119/3c0> <=====
0: 8b 70 5c mov 0x5c(%eax),%esi <=====
Code; c01eb53c <xfs_alloc_lookup+11c/3c0>
3: 89 44 24 0c mov %eax,0xc(%esp,1)
Code; c01eb540 <xfs_alloc_lookup+120/3c0>
7: 89 14 24 mov %edx,(%esp,1)
Code; c01eb543 <xfs_alloc_lookup+123/3c0>
a: 89 6c 24 08 mov %ebp,0x8(%esp,1)
Code; c01eb547 <xfs_alloc_lookup+127/3c0>
e: 89 74 24 04 mov %esi,0x4(%esp,1)
Code; c01eb54b <xfs_alloc_lookup+12b/3c0>
12: e8 10 00 00 00 call 27 <_EIP+0x27>
|