[7343] in Athena Bugs

home help back first fref pref prev next nref lref last post

kernel rfs_readdir

daemon@ATHENA.MIT.EDU (daemon@ATHENA.MIT.EDU)
Wed Mar 20 06:58:55 1991

To: bugs@ATHENA.MIT.EDU
Cc: probe@ATHENA.MIT.EDU, mar@ATHENA.MIT.EDU
Date: Wed, 20 Mar 91 06:58:34 EST
From: John Carr <jfc@ATHENA.MIT.EDU>


Cyrus crashed this morning.  kmem_free paniced:

	kmem_free: free block overlap 812831e8+1536 over 812837a8

Stack trace:

_boot() from _boot+166
_boot(0,0) from _panic+40
_panic(8009f300) from _kmem_free+a2
_kmem_free(812831e8,600) from _rfs_readdir+1c9
_rfs_readdir(81279d98,81264d68) from _afs_rfs_readdir+4a
_afs_rfs_readdir(81279d98,81264d68,7ffffeb8) from 8000e52a
_rfs_dispatch(7ffffeb8,81262198) from _svc_getreq+ca
_svc_getreq(81262198) from _svc_run+37
_svc_run(81262198) from _nfs_svc+ec
_nfs_svc() from _syscall+125
_syscall() from _Xsyscall+c
_Xsyscall(3) from 24e

The bad call is at line 1335 of nfs_server.c.  Before the call there
is code to skip over empty directory entries.  The kmem_free call
frees the memory allocated to the skipped direcetory entries.  There
is a bug in this code:


	skipped = 0;
        while ((skipped < rd->rd_size) &&
            ((offset + dp->d_reclen <= rda->rda_offset) || (dp->d_ino == 0))) {
                skipped += dp->d_reclen;
                offset += dp->d_reclen;
                dp = (struct direct *)((int)dp + dp->d_reclen);
        }

If there are no valid directory entries and the last directory entry
skipped extends past the end of the block being examined, dp will end
up pointing past the end of the allocated block.  The code immediately
following the loop needs to be changed to handle this case:


        /*
         * Reset entries pointer and free space we are skipping
         */
        if (skipped) {
+		if (skipped > rd->rd_size)
+			skipped = rd->rd_size;
                rd->rd_size -= skipped;
                rd->rd_bufsize -= skipped;
                rd->rd_offset = offset;
                kmem_free((caddr_t)rd->rd_entries, (u_int)skipped);


home help back first fref pref prev next nref lref last post