Date: Fri, 29 May 2009 10:02:44 +0000 (UTC) From: Dag-Erling Smorgrav <des@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r193028 - in head/sys: kern sys Message-ID: <200905291002.n4TA2ioQ066842@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: des Date: Fri May 29 10:02:44 2009 New Revision: 193028 URL: http://svn.freebsd.org/changeset/base/193028 Log: 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 Modified: head/sys/kern/vfs_lookup.c head/sys/sys/namei.h Modified: head/sys/kern/vfs_lookup.c ============================================================================== --- head/sys/kern/vfs_lookup.c Fri May 29 09:52:13 2009 (r193027) +++ head/sys/kern/vfs_lookup.c Fri May 29 10:02:44 2009 (r193028) @@ -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 && Modified: head/sys/sys/namei.h ============================================================================== --- head/sys/sys/namei.h Fri May 29 09:52:13 2009 (r193027) +++ head/sys/sys/namei.h Fri May 29 10:02:44 2009 (r193028) @@ -142,7 +142,8 @@ struct nameidata { #define GIANTHELD 0x02000000 /* namei() is holding giant. */ #define AUDITVNODE1 0x04000000 /* audit the looked up vnode information */ #define AUDITVNODE2 0x08000000 /* audit the looked up vnode information */ -#define PARAMASK 0x0ffffe00 /* mask of parameter descriptors */ +#define TRAILINGSLASH 0x10000000 /* path ended in a slash */ +#define PARAMASK 0x1ffffe00 /* mask of parameter descriptors */ #define NDHASGIANT(NDP) (((NDP)->ni_cnd.cn_flags & GIANTHELD) != 0)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905291002.n4TA2ioQ066842>