From owner-p4-projects@FreeBSD.ORG Fri Sep 18 17:37:18 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6D7751065676; Fri, 18 Sep 2009 17:37:18 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 31D1D1065670 for ; Fri, 18 Sep 2009 17:37:18 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 218388FC12 for ; Fri, 18 Sep 2009 17:37:18 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n8IHbI8r013177 for ; Fri, 18 Sep 2009 17:37:18 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n8IHbHrf013175 for perforce@freebsd.org; Fri, 18 Sep 2009 17:37:18 GMT (envelope-from gk@FreeBSD.org) Date: Fri, 18 Sep 2009 17:37:18 GMT Message-Id: <200909181737.n8IHbHrf013175@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Cc: Subject: PERFORCE change 168671 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Sep 2009 17:37:18 -0000 http://perforce.freebsd.org/chv.cgi?CH=168671 Change 168671 by gk@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 +#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); }