nfs bug in 3.2, 3.5 (

forsyth at minster.york.ac.uk forsyth at minster.york.ac.uk
Thu May 11 23:37:02 AEST 1989


There is a nasty bug in nfs_remove (in nfs/nfs_vnodeops.c).  It accepts a
directory vnode pointer & a file name and removes the file from the
directory.  It does an nfs_lookup on the name to produce a vnode pointer
for the file.  It assumes that will also be an NFS vnode.  Unfortunately,
owing to the way that special files were hacked into the vnode system and
NFS as an afterthought, the vnode need not be an rnode (NFS vnode), since
it might be an snode (block or char device vnode) or a fifonode (variant
of snode for FIFOs).  [nfs_lookup calls specvp if it finds a special
file.] But that's all right, since nfs_remove gamely treats it as one of
its own, and if the vnode is still open modifies the r_unldvp and
r_unlname fields of the supposed rnode.  Unfortunately, if the node is in
fact a fifonode, that damages the fn_bufend field and this causes
fifo_buffree to scribble on things or simply blow up when the file is
eventually closed.  Even if the file is closed, nfs_remove calls
nfsattr_inval(vp), which might be benign, but I should not like to rely on
it.

The quickest fix is to add
#define	ISNFS(vp) ((vp)->v_op == &nfs_vnodeops)
and use it at obvious points.
So much for abstraction.

I noticed this because a program that used FIFOs crashed the system when
the fifo was removed whilst open with data in it.  It was surprisingly
hard to track down, not least because of the messy and clumsy nature of
fifo_vnodeops.c.  It goes to considerable effort to avoid a few #ifdefs in
the code; they would be clearer than the hideous rigging of
fifonode::fn_bufend and fifo_bufhdr::fb_next to save 4 bytes per fifo
block if FIFOBUF == FIFOBSZ.  (Those without source can look at
specfs/fifo.h to get the flavour.) The result: the most obscure and
complicated code I have ever seen to handle a FIFO queue.



More information about the Comp.sys.sun mailing list