diff options
author | kib <kib@FreeBSD.org> | 2009-11-10 11:50:37 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-11-10 11:50:37 +0000 |
commit | 2f0558826df54e323e6ce01002e69dc4c0c144e1 (patch) | |
tree | 2186d3eef3404a3fce04d3a1172b08dd177308b8 /sys/kern/vfs_lookup.c | |
parent | cd432c18cdf98aaa39b871b643d199d910a1ee8a (diff) | |
download | FreeBSD-src-2f0558826df54e323e6ce01002e69dc4c0c144e1.zip FreeBSD-src-2f0558826df54e323e6ce01002e69dc4c0c144e1.tar.gz |
When rename("a", "b/.") is performed, target namei() call returns
dvp == vp. Rename syscall does not check for the case, and at least
ufs_rename() cannot deal with it. POSIX explicitely requires that both
rename(2) and rmdir(2) return EINVAL when any of the pathes end in "/.".
Detect the slashdot lookup for RENAME or REMOVE in lookup(), and return
EINVAL.
Reported by: Jim Meyering <jim meyering net>
Tested by: simon, pho
MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r-- | sys/kern/vfs_lookup.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e553ae4..5198562 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -552,6 +552,12 @@ dirloop: else cnp->cn_flags &= ~ISLASTCN; + if ((cnp->cn_flags & ISLASTCN) != 0 && + cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.' && + (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { + error = EINVAL; + goto bad; + } /* * Check for degenerate name (e.g. / or "") |