aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2021-01-27 14:59:53 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2021-01-27 15:08:38 +0000
commit5c325977b1138828367f39a3f2034af24c3654f0 (patch)
treeba5d21a4979842c205905b12f941f248c1f44feb
parent5fc384d1810a3a0a0acefc67abe1daf6d6cd09e4 (diff)
downloadsrc-5c325977b1138828367f39a3f2034af24c3654f0.tar.gz
src-5c325977b1138828367f39a3f2034af24c3654f0.zip
cache: add missing MNT_NOSYMFOLLOW check to symlink traversal
-rw-r--r--sys/kern/vfs_cache.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index be06a2edc58b..ff8aad14001b 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -4816,6 +4816,7 @@ cache_symlink_resolve(struct cache_fpl *fpl, const char *string, size_t len)
static int __noinline
cache_fplookup_symlink(struct cache_fpl *fpl)
{
+ struct mount *mp;
struct nameidata *ndp;
struct componentname *cnp;
struct vnode *dvp, *tvp;
@@ -4832,6 +4833,20 @@ cache_fplookup_symlink(struct cache_fpl *fpl)
}
}
+ mp = atomic_load_ptr(&dvp->v_mount);
+ if (__predict_false(mp == NULL)) {
+ return (cache_fpl_aborted(fpl));
+ }
+
+ /*
+ * Note this check races against setting the flag just like regular
+ * lookup.
+ */
+ if (__predict_false((mp->mnt_flag & MNT_NOSYMFOLLOW) != 0)) {
+ cache_fpl_smr_exit(fpl);
+ return (cache_fpl_handled_error(fpl, EACCES));
+ }
+
error = VOP_FPLOOKUP_SYMLINK(tvp, fpl);
if (__predict_false(error != 0)) {
switch (error) {