summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-09-08 11:25:41 +0000
committertjr <tjr@FreeBSD.org>2004-09-08 11:25:41 +0000
commiteba490783823f36f4f8ec62014ac22c7deae8fbd (patch)
tree4fb05fdd074a06c449c5b797950fa0b34c6d2440
parent1d085394336dc06a0fd195ff4225080701b6fa5f (diff)
downloadFreeBSD-src-eba490783823f36f4f8ec62014ac22c7deae8fbd.zip
FreeBSD-src-eba490783823f36f4f8ec62014ac22c7deae8fbd.tar.gz
Merge from NetBSD:
Fix a problem in previous: we can't blindly assume that we have wincnt entries available at the offset the file has been found. If the dos directory entry is not preceded by appropriate number of long name entries (happens e.g. when the filesystem is corrupted, or when the filename complies to DOS rules and doesn't use any long name entry), we would overwrite random directory entries. There are still some problems, the whole thing has to be revisited and solved right. Submitted by: Xin LI
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 1492098..446f0b2 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -114,7 +114,7 @@ msdosfs_lookup(ap)
int unlen;
int wincnt = 1;
- int chksum = -1;
+ int chksum = -1, chksum_ok;
int olddos = 1;
cnp->cn_flags &= ~PDIRUNLOCK;
@@ -283,7 +283,8 @@ msdosfs_lookup(ap)
/*
* Check for a checksum or name match
*/
- if (chksum != winChksum(dep->deName)
+ chksum_ok = (chksum == winChksum(dep->deName));
+ if (!chksum_ok
&& (!olddos || bcmp(dosfilename, dep->deName, 11))) {
chksum = -1;
continue;
@@ -298,7 +299,21 @@ msdosfs_lookup(ap)
* this lookup.
*/
dp->de_fndoffset = diroff;
- dp->de_fndcnt = wincnt - 1;
+ if (chksum_ok && nameiop == RENAME) {
+ /*
+ * Target had correct long name
+ * directory entries, reuse them
+ * as needed.
+ */
+ dp->de_fndcnt = wincnt - 1;
+ } else {
+ /*
+ * Long name directory entries
+ * not present or corrupt, can only
+ * reuse dos directory entry.
+ */
+ dp->de_fndcnt = 0;
+ }
goto found;
}
OpenPOWER on IntegriCloud