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