Wed, May 27, 2009 at 02:39:07PM +0200, Dag-Erling Sm??rgrav wrote: > I was working on head. The code is (mostly) the same, just shifted > somewhere between ~50 and ~90 lines depending on where you look. Your > patch should apply cleanly. > > BTW, you made a lot of whitespace changes in namei.h. This is generally > frowned upon, as it makes the functional change almost impossible to > spot in the diff.
Yes, spit the patch into two pieces. Thanks for the reminder! > > And yes, I know what was meant by '(cnp->cn_flags & ISSYMLINK) == 0' > > ;)) > > I know you know :) I was just pointing out that the comment is > misleading. Changed it too. All three pieces are attached. Regarding the 'ln -s /etc/motd file; ln -s file/ anotherone': do you (or anyone reading this) think that 'cat anotherone' should really show the contents of /etc/motd or patch's behaviour is good? -- Eygene _ ___ _.--. # \`.|\..----...-'` `-._.-'_.-'` # Remember that it is hard / ' ` , __.--' # to read the on-line manual )/' _/ \ `-_, / # while single-stepping the kernel. `-'" `"\_ ,_.-;_.-\_ ', fsc/as # _.-'_./ {_.' ; / # -- FreeBSD Developers handbook {_.-``-' {_/ #
From 03483c8e800680a8b8a3d3f0d1debdf7fd883906 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin <rea-f...@codelabs.ru> Date: Wed, 27 May 2009 13:13:16 +0400 Subject: [PATCH 1/3] vfs lookups: properly handle the case of slash at the end of symlink If symlink points to a non-directory object but the name has trailing slash, then the current lookup/namei implementation will dereference symlink and return dereferenced object instead of symlink even if NOFOLLOW mode is used. That's not good at all :(( Simple test: ----- $ ln -s /etc/motd file $ file file file: symbolic link to `/etc/motd' [ == Unpatched variant == ] $ file file/ file/: ASCII English text [ == Patched variant == ] $ file file/ file/: cannot open `file/' (Not a directory) ----- See also: http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/21768 See also: http://lists.freebsd.org/pipermail/freebsd-security/2009-May/005219.html Signed-off-by: Eygene Ryabinkin <rea-f...@codelabs.ru> --- sys/kern/vfs_lookup.c | 24 ++++++++++++++++-------- sys/sys/namei.h | 3 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 3770b55..dc801fd 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -138,6 +138,9 @@ namei(struct nameidata *ndp) cnp->cn_flags &= ~LOCKSHARED; fdp = p->p_fd; + /* Drop internal flag: we will set it ourselves if we'll need it. */ + cnp->cn_flags &= ~SLASHTARGET; + /* * Get a buffer for the name to be translated, and copy the * name into the buffer. @@ -683,6 +686,11 @@ unionlookup: ndp->ni_vp = dp = tdp; } + /* Set "slashed" flag if we found slash at the end of the name */ + if (trailing_slash && (cnp->cn_flags & ISLASTCN)) { + cnp->cn_flags |= SLASHTARGET; + } + /* * Check for symbolic link */ @@ -710,14 +718,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, @@ -741,6 +741,14 @@ nextname: goto dirloop; } /* + * Check if we're processing slashed name + * and lookup target isn't a directory. + */ + if ((cnp->cn_flags & SLASHTARGET) && dp->v_type != VDIR) { + error = ENOTDIR; + goto bad2; + } + /* * Disallow directory write attempts on read-only filesystems. */ if (rdonly && diff --git a/sys/sys/namei.h b/sys/sys/namei.h index ac3550d..70e902c 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -146,7 +146,8 @@ struct nameidata { #define GIANTHELD 0x2000000 /* namei() is holding giant. */ #define AUDITVNODE1 0x4000000 /* audit the looked up vnode information */ #define AUDITVNODE2 0x8000000 /* audit the looked up vnode information */ -#define PARAMASK 0xffffe00 /* mask of parameter descriptors */ +#define SLASHTARGET 0x10000000 /* last component of the name was slashed */ +#define PARAMASK 0x1ffffe00 /* mask of parameter descriptors */ #define NDHASGIANT(NDP) (((NDP)->ni_cnd.cn_flags & GIANTHELD) != 0) -- 1.6.3.1
From 2539d4f31a2f85504672e8113343242782e737a7 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin <rea-f...@codelabs.ru> Date: Wed, 27 May 2009 17:06:39 +0400 Subject: [PATCH 2/3] namei.h: realign numbers Functional no-op, just for the eye's pleasure. Signed-off-by: Eygene Ryabinkin <rea-f...@codelabs.ru> --- sys/sys/namei.h | 39 ++++++++++++++++++++------------------- 1 files changed, 20 insertions(+), 19 deletions(-) diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 70e902c..c84a823 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -127,25 +127,26 @@ struct nameidata { * name being sought. The caller is responsible for releasing the * buffer and for vrele'ing ni_startdir. */ -#define RDONLY 0x0000200 /* lookup with read-only semantics */ -#define HASBUF 0x0000400 /* has allocated pathname buffer */ -#define SAVENAME 0x0000800 /* save pathname buffer */ -#define SAVESTART 0x0001000 /* save starting directory */ -#define ISDOTDOT 0x0002000 /* current component name is .. */ -#define MAKEENTRY 0x0004000 /* entry is to be added to name cache */ -#define ISLASTCN 0x0008000 /* this is last component of pathname */ -#define ISSYMLINK 0x0010000 /* symlink needs interpretation */ -#define ISWHITEOUT 0x0020000 /* found whiteout */ -#define DOWHITEOUT 0x0040000 /* do whiteouts */ -#define WILLBEDIR 0x0080000 /* new files will be dirs; allow trailing / */ -#define ISUNICODE 0x0100000 /* current component name is unicode*/ -#define ISOPEN 0x0200000 /* caller is opening; return a real vnode. */ -#define NOCROSSMOUNT 0x0400000 /* do not cross mount points */ -#define NOMACCHECK 0x0800000 /* do not perform MAC checks */ -#define MPSAFE 0x1000000 /* namei() must acquire Giant if needed. */ -#define GIANTHELD 0x2000000 /* namei() is holding giant. */ -#define AUDITVNODE1 0x4000000 /* audit the looked up vnode information */ -#define AUDITVNODE2 0x8000000 /* audit the looked up vnode information */ +#define RDONLY 0x00000200 /* lookup with read-only semantics */ +#define HASBUF 0x00000400 /* has allocated pathname buffer */ +#define SAVENAME 0x00000800 /* save pathname buffer */ +#define SAVESTART 0x00001000 /* save starting directory */ +#define ISDOTDOT 0x00002000 /* current component name is .. */ +#define MAKEENTRY 0x00004000 /* entry is to be added to name cache */ +#define ISLASTCN 0x00008000 /* this is last component of pathname */ +#define ISSYMLINK 0x00010000 /* symlink needs interpretation */ +#define ISWHITEOUT 0x00020000 /* found whiteout */ +#define DOWHITEOUT 0x00040000 /* do whiteouts */ +#define WILLBEDIR 0x00080000 /* new files will be dirs; + * allow trailing / */ +#define ISUNICODE 0x00100000 /* current component name is unicode*/ +#define ISOPEN 0x00200000 /* caller is opening; return a real vnode. */ +#define NOCROSSMOUNT 0x00400000 /* do not cross mount points */ +#define NOMACCHECK 0x00800000 /* do not perform MAC checks */ +#define MPSAFE 0x01000000 /* namei() must acquire Giant if needed. */ +#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 SLASHTARGET 0x10000000 /* last component of the name was slashed */ #define PARAMASK 0x1ffffe00 /* mask of parameter descriptors */ -- 1.6.3.1
From e92f5e9751e04d458c3d8fcbd53d3cd727b1e75f Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin <rea-f...@codelabs.ru> Date: Wed, 27 May 2009 17:08:46 +0400 Subject: [PATCH 3/3] vfs_lookup: change misleading comment in namei() Signed-off-by: Eygene Ryabinkin <rea-f...@codelabs.ru> --- sys/kern/vfs_lookup.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index dc801fd..860bea0 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -227,7 +227,7 @@ namei(struct nameidata *ndp) vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0; ndp->ni_cnd.cn_flags &= ~GIANTHELD; /* - * Check for symbolic link + * If not a symbolic link, we're done. */ if ((cnp->cn_flags & ISSYMLINK) == 0) { if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) { -- 1.6.3.1
_______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"