DF-5809 / fix.diff
--- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2294,6 +2294,35 @@ return (0); } +/* + * DF-5809: safe variant. Extract the export flags and snapshot the + * anonymous credential while NE_LOCK is still held, so the caller never + * dereferences the netcred after the lock is released. The returned + * credential snapshot is a value copy owned by the caller; it must not + * be crfree()d (it is not refcounted), mirroring the embedded + * netc_anon semantics consumers already expect. + * + * Returns 0 on success with *exflagsp / *credanonp filled in, + * EACCES if no export matched. + */ +int +vfs_export_lookup_locked(struct mount *mp, struct netexport *nep, + struct sockaddr *nam, int *exflagsp, + struct ucred *credanonp) +{ + struct netcred *np; + + np = vfs_export_lookup(mp, nep, nam); + if (np == NULL) + return (EACCES); + NE_LOCK(nep); + *exflagsp = np->netc_exflags; + if (credanonp) + *credanonp = np->netc_anon; + NE_UNLOCK(nep); + return (0); +} + struct netcred * vfs_export_lookup(struct mount *mp, struct netexport *nep, struct sockaddr *nam) # NOTE (not part of the patch): every VFS_CHECKEXP consumer must be # converted to the *_locked() variant, e.g. ufs_vfsops.c:246-251 becomes # # int exflags; # struct ucred credanon; # # error = vfs_export_lookup_locked(mp, &ump->um_export, nam, # &exflags, &credanon); # if (error) # return (error); # *exflagsp = exflags; # *credanonp = &credanon; /* caller-owned storage, no netcred deref */ # # same mechanical change in tmpfs, hammer2, cd9660, nullfs, ntfs, # msdosfs, udf checkexp implementations. |