diff options
author | des <des@FreeBSD.org> | 2009-05-29 10:02:44 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2009-05-29 10:02:44 +0000 |
commit | ae136aabf041855e6890b6d5505e5563af926a50 (patch) | |
tree | bc73c15012b278d07002bc2e375c60780d21d59f /sys/kern/vfs_lookup.c | |
parent | 0df4f0c59f01f29867e702b44590ed627943dba5 (diff) | |
download | FreeBSD-src-ae136aabf041855e6890b6d5505e5563af926a50.zip FreeBSD-src-ae136aabf041855e6890b6d5505e5563af926a50.tar.gz |
Let vfs_lookup() return ENOTDIR if the path has a trailing slash and
the last component is a symlink to something that isn't a directory.
We introduce a new namei flag, TRAILINGSLASH, which is set by lookup()
if the last component is followed by a slash. The trailing slash is
then stripped, as before. If the final component is a symlink,
lookup() will return to namei(), which will expand the symlink and
call lookup() with the new path. When all symlinks have been
resolved, lookup() checks if the TRAILINGSLASH flag is set, and if it
is, and the vnode it ended up with is not a directory, it returns
ENOTDIR.
PR: kern/21768
Submitted by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
MFC after: 3 weeks
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r-- | sys/kern/vfs_lookup.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 98f4274..c76bd5b 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -147,6 +147,9 @@ namei(struct nameidata *ndp) cnp->cn_flags &= ~LOCKSHARED; fdp = p->p_fd; + /* We will set this ourselves if we need it. */ + cnp->cn_flags &= ~TRAILINGSLASH; + /* * Get a buffer for the name to be translated, and copy the * name into the buffer. @@ -533,6 +536,7 @@ dirloop: if (*cp == '\0') { trailing_slash = 1; *ndp->ni_next = '\0'; /* XXX for direnter() ... */ + cnp->cn_flags |= TRAILINGSLASH; } } ndp->ni_next = cp; @@ -807,14 +811,6 @@ unionlookup: goto success; } - /* - * Check for bogus trailing slashes. - */ - if (trailing_slash && dp->v_type != VDIR) { - error = ENOTDIR; - goto bad2; - } - nextname: /* * Not a symbolic link. If more pathname, @@ -838,6 +834,14 @@ nextname: goto dirloop; } /* + * If we're processing a path with a trailing slash, + * check that the end result is a directory. + */ + if ((cnp->cn_flags & TRAILINGSLASH) && dp->v_type != VDIR) { + error = ENOTDIR; + goto bad2; + } + /* * Disallow directory write attempts on read-only filesystems. */ if (rdonly && |