xfs
[Top] [All Lists]

XFS NULL pointer dereference at virtual address 0000005c

To: linux-xfs@xxxxxxxxxxx
Subject: XFS NULL pointer dereference at virtual address 0000005c
From: Jim Minter <jim@xxxxxxxxxxxxxxxxxx>
Date: Mon, 17 Nov 2003 13:21:14 +0000
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: KMail/1.5.4
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>


<Prev in Thread] Current Thread [Next in Thread>