PERFORCE change 168671 for review

Gleb Kurtsou gk at FreeBSD.org
Fri Sep 18 17:37:18 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=168671

Change 168671 by gk at gk_h1 on 2009/09/18 17:37:04

	fix mouting on top of ufs:
	fix incorrect readdir result parsing
	pefs_name_{ntop,pton}: return error on empty result
	
	fix sbin/pefs incorrect fs root

Affected files ...

.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#6 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#10 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#15 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_xbase64.c#4 edit

Differences ...

==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#6 (text+ko) ====

@@ -119,7 +119,7 @@
 	}
 
 	if (fsroot != NULL)
-		strlcpy(fsroot, fs.f_mntfromname, size);
+		strlcpy(fsroot, fs.f_mntonname, size);
 
 	return (0);
 }

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#10 (text+ko) ====

@@ -437,6 +437,7 @@
 {
 	size_t psize;
 
+	MPASS(namelen > PEFS_NAME_CSUM_SIZE && namelen < MAXNAMLEN + 1);
 	psize = namelen - PEFS_NAME_CSUM_SIZE;
 	psize = PEFS_NAME_CSUM_SIZE + 
 	    PEFS_BLOCK_ROUND(PEFS_CSUM_BLOCK_SIZE, psize);
@@ -517,6 +518,9 @@
 
 	enc[0] = '.';
 	r = pefs_name_ntop(buf, size, enc + 1, enc_size - 1);
+	if (r <= 0)
+		return (r);
+	r++;
 
 	return (r);
 }
@@ -542,7 +546,7 @@
 	if (PEFS_NAME_PTON_SIZE(enc_len) <= PEFS_TWEAK_SIZE + PEFS_NAME_CSUM_SIZE)
 		return (-EINVAL);
 	r = pefs_name_pton(enc, enc_len, plain, plain_size);
-	if (r < 0) {
+	if (r <= 0) {
 		PEFSDEBUG("pefs_name_decrypt: error: r=%d\n", r);
 		return (-EINVAL);
 	}

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#15 (text+ko) ====

@@ -68,6 +68,8 @@
 
 #include <fs/pefs/pefs.h>
 
+#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN + 1))
+
 static int pefs_bug_bypass = 0;   /* for debugging: enables bypass printf'ing */
 SYSCTL_INT(_debug, OID_AUTO, pefs_bug_bypass, CTLFLAG_RW,
 	&pefs_bug_bypass, 0, "");
@@ -193,14 +195,15 @@
 	struct dirent *de;
 	char buf[MAXNAMLEN + 1];
 	int d_namelen;
-	int de_len;
 
 	PEFSDEBUG("pefs_enccn_lookup_dirent: lookup %.*s\n", (int)namelen, name);
 	ctx = pefs_ctx_get();
-	for (de = (struct dirent*) mem; sz > 0;
-			sz -= de_len,
-			de = (struct dirent *)(((caddr_t)de) + de_len)) {
-		de_len = GENERIC_DIRSIZ(de);
+	for (de = (struct dirent*) mem; sz > DIRENT_MINSIZE;
+			sz -= de->d_reclen,
+			de = (struct dirent *)(((caddr_t)de) + de->d_reclen)) {
+		MPASS(de->d_reclen <= sz);
+		if (de->d_type == DT_WHT)
+			continue;
 		if (pefs_name_skip(de->d_name, de->d_namlen))
 			continue;
 		d_namelen = pefs_name_decrypt(ctx, pk, ptk, de->d_name,
@@ -552,18 +555,31 @@
 	if (!nokey_lookup) {
 		error = pefs_enccn_lookup(&enccn, dvp, cnp);
 		if (error == ENOENT && (cnp->cn_flags & ISLASTCN) &&
-		    (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)) {
-			PEFSDEBUG("pefs_lookup: just return %.*s\n",
-			    (int)cnp->cn_namelen, cnp->cn_nameptr);
-			error = EJUSTRETURN;
+		    (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME ||
+		    (cnp->cn_nameiop == DELETE &&
+		    (cnp->cn_flags & DOWHITEOUT) &&
+		    (cnp->cn_flags & ISWHITEOUT)))) {
+			/* 
+			 * Some filesystems (like ufs) update internal inode
+			 * fields during VOP_LOOKUP which are later used by
+			 * VOP_CREATE, VOP_MKDIR, etc. That's why we can't
+			 * return EJUSTRETURN here and have to perform
+			 * VOP_LOOKUP(ldvp).
+			 * Attention should also be paid not to unlock dvp.
+			 *
+			 * XXX We also need to have a valid encrypted cnp. Real
+			 * encrypted cnp will be created anyway, encrypted name
+			 * length should just be the same here.
+			 */
+			pefs_enccn_create_node(&enccn, dvp, cnp);
+			error = 0;
 		}
 
 		if (error == 0) {
 			error = VOP_LOOKUP(ldvp, &lvp, &enccn.pec_cn);
 			if (error == 0 || error == EJUSTRETURN) {
-				/* XXX only SAVENAME can be changed ?? */
-				cnp->cn_flags = (enccn.pec_cn.cn_flags &
-				    ~HASBUF) | (cnp->cn_flags & HASBUF);
+				cnp->cn_flags = (cnp->cn_flags & HASBUF) |
+				    (enccn.pec_cn.cn_flags & ~HASBUF);
 			}
 			if (error != 0)
 				PEFSDEBUG("pefs_lookup: lower error = %d\n", error);
@@ -1170,14 +1186,15 @@
 	char buf[MAXNAMLEN + 1];
 	size_t sz;
 	int d_namelen;
-	int de_len;
 
 	ctx = pefs_ctx_get();
-	for (de = (struct dirent*) mem, sz = *psize; sz > 0; de = de_next) {
-		de_len = GENERIC_DIRSIZ(de);
-		MPASS(sz >= de_len);
-		sz -= de_len;
-		de_next = (struct dirent *)(((caddr_t)de) + de_len);
+	for (de = (struct dirent*) mem, sz = *psize; sz > DIRENT_MINSIZE;
+	    de = de_next) {
+		MPASS(de->d_reclen <= sz);
+		sz -= de->d_reclen;
+		de_next = (struct dirent *)(((caddr_t)de) + de->d_reclen);
+		if (de->d_type == DT_WHT)
+			continue;
 
 		if (pefs_name_skip(de->d_name, de->d_namlen))
 			continue;
@@ -1187,8 +1204,8 @@
 			strlcpy(de->d_name, buf, de->d_namlen + 1);
 			de->d_namlen = d_namelen;
 		} else if (dflags & PN_HASKEY) {
+			*psize -= de->d_reclen;
 			memcpy(de, de_next, sz);
-			*psize -= de_len;
 			de_next = de;
 		}
 	}
@@ -1247,7 +1264,7 @@
 		uio->uio_offset = puio->uio_offset;
 
 		/* Finish if there is no need to merge cookies */
-		if ((*eofflag || uio->uio_resid < sizeof(struct dirent)) &&
+		if ((*eofflag || uio->uio_resid <= DIRENT_MINSIZE) &&
 		    (a_cookies == NULL || r_cookies == NULL))
 			break;
 
@@ -1256,7 +1273,7 @@
 			if (r_cookies == NULL) {
 				/* Allocate buffer of maximum possible size */
 				r_ncookies_max = uio->uio_resid /
-				    (sizeof(struct dirent) - MAXNAMLEN);
+				    DIRENT_MINSIZE;
 				r_ncookies_max += ncookies;
 				r_cookies = malloc(r_ncookies_max * sizeof(u_long),
 				    M_TEMP, M_WAITOK);
@@ -1273,7 +1290,7 @@
 			cookies = NULL;
 		}
 
-		if (*eofflag || uio->uio_resid < sizeof(struct dirent))
+		if (*eofflag || uio->uio_resid <= DIRENT_MINSIZE)
 			break;
 
 		pefs_chunk_restore(&pc);

==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_xbase64.c#4 (text+ko) ====

@@ -119,7 +119,7 @@
 			target[datalength++] = Base64[output[2]];
 		}
 	}
-	if (datalength >= targsize)
+	if (datalength >= targsize || datalength == 0)
 		return (-1);
 	target[datalength] = '\0';	/* Returned value doesn't count \0. */
 	return (datalength);
@@ -181,5 +181,7 @@
 		}
 	}
 
+	if (tarindex == 0)
+		return (-1);
 	return (tarindex);
 }


More information about the p4-projects mailing list