Examining assembly code: vno_rw()


If we examine the assembly instructions of vno_rw() , we see that it does pass the valid vnode pointer to fifo_rdwr() .

  vno_rw,10/ia  _vno_rw:   _vno_rw:        save    %sp, -0x60, %sp   _vno_rw+4:      ld      [%i0 + 0x10], %i4  <---   Load vp into %i4  _vno_rw+8:      cmp     %i1, 0x1   _vno_rw+0xc:    bne,a   _vno_rw + 0x30   _vno_rw+0x10:   ld      [%i2 + 0x10], %i3   _vno_rw+0x14:   call    _isrofile  <---   Is vp pointing to read-only file?  _vno_rw+0x18:   mov     %i4, %o0  <---   Copy vp into %o0 during call delay  _vno_rw+0x1c:   orcc    %g0, %o0, %g0   _vno_rw+0x20:   be,a    _vno_rw + 0x30  <---   Read write, branch to 30  _vno_rw+0x24:   ld      [%i2 + 0x10], %i3   _vno_rw+0x28:   ba      _vno_rw + 0xf4  <---   Read-only, branch to return  _vno_rw+0x2c:   mov     0x1e, %i5   _vno_rw+0x30:   ld      [%i4 + 0x18], %o0  <---   Using %o0 as a local register  _vno_rw+0x34:   clr     %i5  now. Watch how it is used  _vno_rw+0x38:   cmp     %o0, 0x1  but is reset to the vp just  _vno_rw+0x3c:   bne,a   _vno_rw + 0x4c  as we jump into a vnode  _vno_rw+0x40:  operations routine later on.   +,10/ia  _vno_rw+0x40:   ld      [%i0], %o1   _vno_rw+0x44:   mov     0x1, %i5   _vno_rw+0x48:   ld      [%i0], %o1   _vno_rw+0x4c:   andcc   %o1, 0x8, %g0   _vno_rw+0x50:   be,a    _vno_rw + 0x60   _vno_rw+0x54:   ld      [%i0], %o2   _vno_rw+0x58:   or      %i5, 0x2, %i5   _vno_rw+0x5c:   ld      [%i0], %o2   _vno_rw+0x60:   sethi   %hi(0x2000), %o3   _vno_rw+0x64:   andcc   %o2, %o3, %g0   _vno_rw+0x68:   be,a    _vno_rw + 0x78   _vno_rw+0x6c:   ld      [%i0], %o4   _vno_rw+0x70:   or      %i5, 0x4, %i5   _vno_rw+0x74:   ld      [%i0], %o4   _vno_rw+0x78:   sethi   %hi(0x1000), %o5   _vno_rw+0x7c:   andcc   %o4, %o5, %g0   _vno_rw+0x80:  +,10/ia  _vno_rw+0x80:   be,a    _vno_rw + 0x90   _vno_rw+0x84:   ld      [%i4 + 0xc], %g1  <---   This area of code is using a table  _vno_rw+0x88:   or      %i5, 0x10, %i5  of file system operations to figure  _vno_rw+0x8c:   ld      [%i4 + 0xc], %g1  out where we want to jump, based  _vno_rw+0x90:   mov     %i5, %o3  on our file system type. The final  _vno_rw+0x94:   ld      [%g1 + 0x8], %g1  address is in %g1.  _vno_rw+0x98:   ld      [%i0 + 0x18], %o4  <---   Start preparing calling parameters.  _vno_rw+0x9c:   mov     %i1, %o2   _vno_rw+0xa0:   mov     %i2, %o1   _vno_rw+0xa4:   jmpl    %g1, %o7  <---   Jump into fifo_rdwr, moving vp  _vno_rw+0xa8:   mov     %i4, %o0  <---   into %o1 during the jmpl delay.  _vno_rw+0xac:   mov     %o0, %i5   _vno_rw+0xb0:   orcc    %g0, %i5, %g0   _vno_rw+0xb4:   bne     _vno_rw + 0xf4   _vno_rw+0xb8:   nop   _vno_rw+0xbc:   ld      [%i0], %l0   _vno_rw+0xc0:  +,10/ia  _vno_rw+0xc0:   andcc   %l0, 0x8, %g0   _vno_rw+0xc4:   bne,a   _vno_rw + 0xe0   _vno_rw+0xc8:   ld      [%i2 + 0x10], %l4   _vno_rw+0xcc:   ld      [%i4 + 0x18], %i4   _vno_rw+0xd0:   cmp     %i4, 0x8   _vno_rw+0xd4:   bne,a   _vno_rw + 0xf4   _vno_rw+0xd8:   clr     %i5   _vno_rw+0xdc:   ld      [%i2 + 0x10], %l4   _vno_rw+0xe0:   ld      [%i2 + 0x8], %i2   _vno_rw+0xe4:   sub     %i3, %l4, %l4   _vno_rw+0xe8:   sub     %i2, %l4, %l4   _vno_rw+0xec:   st      %l4, [%i0 + 0x14]   _vno_rw+0xf0:   clr     %i5   _vno_rw+0xf4:   ret   _vno_rw+0xf8:   restore %g0, %i5, %o0   _vno_ioctl:   _vno_ioctl:     save    %sp, -0xb8, %sp   _vno_ioctl+4: 

So far, it appears that a good vnode pointer was given to fifo_rdwr() . What about the other calling parameters? Since vno_rw() is a somewhat short and rather easy-to-follow routine, we can also check the parameters without going through too much pain. Refer to the assembly code above.

  $c  _panic(0xf8120eb1,0xf86e8cbc,0xffffffff,0x30,0x7c375,0xf7fffdf0) + 6c  _trap(0x7,0xf86e8cbc,0xffffffff,0x30,0x0,0x0) + 2a0  st_have_window(?)  _uiomove(0x0,0x0,0x1000,0x2,0x1002,0x2) + 98  _fifo_rdwr(0xfceaccb0,0xf86e8eac,0x0,0xfceb2525,0x2,0x0) + 5ac  _vno_rw(0xf835bac8,0x1,0xf86e8eac,0x1000,0xfceaccb4,0x0) + a4  _rwuio(0xf835bac8,0xf86e8eac,0xf86e8ea4,0x1000,0x1000,0xf86e8eac) + 2b0  _write(0xf86e8fe0,0x20,0xf8114ad0,0xf8114af0,0xf86e9000,0xf8114af0) + 34  _syscall(0xf86e9000) + 3b4  0xf835bac8+18/X  0xf835bae0:     ff1c1514  <----   See vno_rw+0x98. %o4 points to a credentials structure.   ff1c1514$<ucred  0xff1c1514:     ref     uid        gid                  5       0          1  0xff1c1520:     groups                  0                  -1                 -1                     -1                  -1                 -1                 -1                     -1  0xff1c151c:     ruid    rgid                  0       1  0xf86e8eac$<uio             <----   See vno_rw+0xa0. %o1 contains a uio pointer.  0xf86e8eac:     iovcnt             offset            seg        resid                  1                  4096              0          0  0xf86e8ea4:     base  7630                  len   0  7630/X  0x7630:         ff8 

As we can see, when vno_rw() called fifo_rdwr() , three apparently valid pointers were sent as parameters vp , uiop , and cred . The other two parameters, rw and ioflag , are both small values. Ioflag was created on-the-fly by vno_rw() and rw was simply forwarded.

We can safely assume things were going along well until we were executing the fifo_rdwr() routine. But, where exactly did things go wrong? Since fifo_rdwr() i s a long routine, without source code this question is not easily answered .



PANIC. UNIX System Crash Dump Analysis Handbook
PANIC! UNIX System Crash Dump Analysis Handbook (Bk/CD-ROM)
ISBN: 0131493868
EAN: 2147483647
Year: 1994
Pages: 289
Authors: Chris Drake

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net