For each file in sysctl(KERN_FILE_BYFILE), FILLIT() calls fill_file(),
authorbluhm <bluhm@openbsd.org>
Mon, 18 May 2015 19:10:35 +0000 (19:10 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 18 May 2015 19:10:35 +0000 (19:10 +0000)
commit3bdb371dc568b419dbc8a837f4df88f00c63711c
treec81883d539bcbab1fa5d9a4390806ff1e6a0b333
parent8529ddd3cf8b8ffce3ab6c5b64acddb7831726a7
For each file in sysctl(KERN_FILE_BYFILE), FILLIT() calls fill_file(),
which calls VOP_GETATTR().  For NFS, that leads to nfs_getattr().
If the node's attributes are not in NFS's cache, nfs_getattr() will
invoke nfs_request() and the latter will sleep, allowing the file
pointer to disappear while we traverse the list.
This results in kernel crashes while running netstat or pstat -f.
Grab a reference to the file descriptor before calling FILLIT(),
and release it afterwards.  This way the file descriptor cannot
disappear while we sleep in nfs_getattr().
Analysis and fix from Pedro Martelletto; input and OK guenther@ mpi@
sys/kern/kern_sysctl.c