summaryrefslogtreecommitdiff
path: root/sys/msdosfs
diff options
context:
space:
mode:
authorTom Cosgrove <tom@cvs.openbsd.org>2005-03-02 00:35:05 +0000
committerTom Cosgrove <tom@cvs.openbsd.org>2005-03-02 00:35:05 +0000
commitf453946fa42c02de8db6f9d9c03912d9ab81e6c6 (patch)
treebed8657b5573c108bf6bd7d3bd7deb68c21bb340 /sys/msdosfs
parent6597e2214de6dfd5c794368e202c21b3bc1c275b (diff)
Make all the MS-DOS filesystem code ignore trailing dots and spaces, in
the same way that Windows does. Without this, `touch .foobar.' followed by `touch .foobar.' will create two directory entries called `.foobar', thereby corrupting the filesystem. Found by todd@, who has been doing things with msdosfs that are truly obscene. "alright" tedu@, ok deraadt@
Diffstat (limited to 'sys/msdosfs')
-rw-r--r--sys/msdosfs/msdosfs_lookup.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c
index 9c53722a5b7..226bccb896d 100644
--- a/sys/msdosfs/msdosfs_lookup.c
+++ b/sys/msdosfs/msdosfs_lookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_lookup.c,v 1.14 2004/05/14 04:05:05 tedu Exp $ */
+/* $OpenBSD: msdosfs_lookup.c,v 1.15 2005/03/02 00:35:04 tom Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.34 1997/10/18 22:12:27 ws Exp $ */
/*-
@@ -110,6 +110,8 @@ msdosfs_lookup(v)
struct buf *bp = 0;
struct direntry *dep;
u_char dosfilename[12];
+ u_char *adjp;
+ int adjlen;
int flags;
int nameiop = cnp->cn_nameiop;
int wincnt = 1;
@@ -200,9 +202,25 @@ msdosfs_lookup(v)
dosfilename, cnp->cn_namelen);
#endif
/*
- * Search the directory pointed at by vdp for the name pointed at
- * by cnp->cn_nameptr.
+ * We want to search the directory pointed to by vdp for the name
+ * pointed to by cnp->cn_nameptr.
+ *
+ * XXX UNIX allows filenames with trailing dots and blanks; we don't.
+ * Most of the routines in msdosfs_conv.c adjust for this, but
+ * winChkName() does not, so we do it here. Otherwise, a file
+ * such as ".foobar." cannot be retrieved properly.
+ *
+ * (Note that this is also faster: perform the adjustment once,
+ * rather than on each call to winChkName. However, it is still
+ * a nasty hack.)
*/
+ adjp = cnp->cn_nameptr;
+ adjlen = cnp->cn_namelen;
+
+ for (adjp += adjlen; adjlen > 0; adjlen--)
+ if (*--adjp != ' ' && *adjp != '.')
+ break;
+
tdp = NULL;
/*
* The outer loop ranges over the clusters that make up the
@@ -267,7 +285,7 @@ msdosfs_lookup(v)
continue;
chksum = winChkName((u_char *)cnp->cn_nameptr,
- cnp->cn_namelen,
+ adjlen,
(struct winentry *)dep,
chksum);
continue;