socsvn commit: r236400 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs sys/modules/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Fri May 25 16:26:09 UTC 2012
Author: gpf
Date: Fri May 25 16:26:06 2012
New Revision: 236400
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=236400
Log:
Require that .pefs.checksum is created outside of target pefs filesystem.
Change pefs_ioctl() kernel panics into printfs() and error returns.
Modified:
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c
soc2012/gpf/pefs_kmod/sys/modules/pefs/Makefile
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Fri May 25 16:26:06 2012 (r236400)
@@ -227,7 +227,7 @@
if (checksum_hash_tablep->buckets != NULL) {
for (i = 0; i < checksum_hash_tablep->size; i++) {
bp = &checksum_hash_tablep->buckets[i];
- LIST_FOREACH_SAFE(fhp, &(bp->file_headers), bucket_entries, tfhp) {
+ LIST_FOREACH_SAFE(fhp, &(bp->file_headers), bucket_entries, tfhp) {
TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) {
TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries);
if (csp->hash != NULL)
@@ -355,6 +355,8 @@
if (error == 0)
fhp->file_id = namemac.pnm_csum;
+ else
+ pefs_warn("failed to fetch file id from kernel");
close(fd);
return (error);
@@ -674,12 +676,52 @@
}
/*
+ * If .pefs.checksum is created inside pefs mounted fs, then it will obtain an
+ * encrypted filename & encrypted data, which is unacceptable. User should create
+ * checksum file outside of filesystem and then copy it by hand.
+ */
+static int
+pefs_open_checksum_file(int *fdp, char *fsroot, char *csm_path)
+{
+ struct statfs pefs_fs, checksum_fs;
+ int fd;
+
+ *fdp = -1;
+
+ fd = open(csm_path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ warn("cannot open %s", csm_path);
+ return (PEFS_ERR_IO);
+ }
+
+ *fdp = fd;
+
+ if (statfs(fsroot, &pefs_fs) == -1) {
+ pefs_warn("statfs failed: %s: %s", fsroot, strerror(errno));
+ return (PEFS_ERR_SYS);
+ }
+
+ if (statfs(csm_path, &checksum_fs) == -1) {
+ pefs_warn("statfs failed: %s: %s", csm_path, strerror(errno));
+ return (PEFS_ERR_SYS);
+ }
+
+ if ((pefs_fs.f_fsid.val[0] == checksum_fs.f_fsid.val[0]) &&
+ (pefs_fs.f_fsid.val[1] == checksum_fs.f_fsid.val[1])) {
+ pefs_warn("%s must be created outside of pefs mounted filesystem %s",
+ csm_path, pefs_fs.f_mntonname);
+ return (PEFS_ERR_INVALID);
+ }
+
+ return (0);
+}
+
+/*
* XXXgpf: [TODO] proper comment header, I am sleepy Z_Z
*/
int
-pefs_create_checksum_file(FILE *fpin, char *fsroot, const char *algo)
+pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path, const char *algo)
{
- char checksum_path[MAXPATHLEN];
struct hash_table checksum_hash_table;
struct checksum_file_header cfh;
const EVP_MD *md;
@@ -695,21 +737,12 @@
}
hash_len = EVP_MD_size(md);
- snprintf(checksum_path, sizeof(checksum_path), "%s/%s", fsroot, PEFS_FILE_CHECKSUM);
- /*
- * XXXgpf: [TODO] If pefs fs is mounted when .pefs.checksum is created, then it will obtain an
- * encrypted filename & encrypted data. I should make sure that checksum file is not being
- * opened inside a mounted pefs filesystem.
- * pefs_open_checksum_file()
- */
- fdout = open(checksum_path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
- if (fdout == -1) {
- warn("cannot open %s", checksum_path);
- return (PEFS_ERR_IO);
- }
-
pefs_init_hash_table(&checksum_hash_table);
+ error = pefs_open_checksum_file(&fdout, fsroot, csm_path);
+ if (error != 0)
+ goto out;
+
error = pefs_create_in_memory_db(fpin, md, hash_len,
&checksum_hash_table, fsroot);
if (error != 0)
@@ -720,10 +753,11 @@
error = pefs_write_checksum_file(fdout, &cfh, &checksum_hash_table);
out:
- if (fdout >= 0)
+ if (fdout >= 0) {
close(fdout);
- if (error != 0)
- unlink(checksum_path);
+ if (error != 0)
+ unlink(csm_path);
+ }
pefs_free_hash_table(&checksum_hash_table);
return (error);
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Fri May 25 16:26:06 2012 (r236400)
@@ -1011,27 +1011,33 @@
/*
* XXXgpf: Instead of a man page entry:
*
- * pefs addchecksum [-a algo] [-i inputfile] filesystem
+ * pefs addchecksum [-a algo] [-i inputfile] [-p path] filesystem
*
* $command creates .pefs.checksum db file for filesystem.
* This file will contain all checksums necessary to check integrity
* of files upon access.
*
* algo is the name of the algorithm to be used as a cryptographic
- * hash function; supported algorithms: sha256, sha512.
+ * hash function; supported algorithms: sha256, sha512. sha256 is
+ * used by default.
*
- * inputfile contains list of files that need integrity checking.
+ * inputfile contains list of files that need integrity checking. An
+ * inputfile must be supplied.
+ *
+ * path defines where .pefs.checksum should be created. By default,
+ * .pefs.checksum is created under $PWD. path should be a directory,
+ * outside of target pefs filesystem.
*
- * When $command is run, filesystem should be already mounted with
+ * When $command is run, filesystem should be already mounted with
* pefs.
- *
- * [TODO] reference for where .pefs.checksum file should be created.
*
*/
static int
pefs_addchecksum(int argc, char *argv[])
{
char fsroot[MAXPATHLEN];
+ char csm_path[MAXPATHLEN];
+ struct stat sb;
FILE *fpin;
int error, i, j;
const char *algo;
@@ -1039,8 +1045,11 @@
fpin = NULL;
/* by default use sha256 */
algo = supported_digests[0];
+ /* by default create checksum file under $PWD */
+ snprintf(csm_path, sizeof(csm_path), "./%s", PEFS_FILE_CHECKSUM);
- while ((i = getopt(argc, argv, "a:i:")) != -1)
+ /* XXXgpf: [TODO] add argument for user to specify path for .pefs. checksum */
+ while ((i = getopt(argc, argv, "a:i:p:")) != -1)
switch(i) {
case 'a':
for (j=0; j < PEFS_SUPPORTED_DIGESTS; j++)
@@ -1063,6 +1072,23 @@
goto out;
}
break;
+ case 'p':
+ if (stat(optarg, &sb) != 0) {
+ warn("cannot stat file %s", optarg);
+ error = PEFS_ERR_INVALID;
+ goto out;
+ }
+
+ if (S_ISDIR(sb.st_mode) == 0) {
+ pefs_warn("filename: %s is not a directory", optarg);
+ error = PEFS_ERR_INVALID;
+ goto out;
+ }
+
+ snprintf(csm_path, sizeof(csm_path), "%s/%s", optarg,
+ PEFS_FILE_CHECKSUM);
+
+ break;
default:
if (fpin != NULL)
fclose(fpin);
@@ -1079,7 +1105,7 @@
initfsroot(argc, argv, 0, fsroot, sizeof(fsroot));
- error = pefs_create_checksum_file(fpin, fsroot, algo);
+ error = pefs_create_checksum_file(fpin, fsroot, csm_path, algo);
out:
if (fpin != NULL)
@@ -1209,8 +1235,8 @@
" pefs randomchain [-fv] [-n min] [-N max] filesystem\n"
" pefs showchains [-fp] [-i iterations] [-k keyfile] filesystem\n"
" pefs showalgs\n"
-" pefs addchecksum [-a algo] [-i inputfile] filesystem\n"
-" pefs addchecklist [-i inputfile] [-o outputfile[ filesystem\n"
+" pefs addchecksum [-a algo] [-i inputfile] [-p checksumpath] filesystem\n"
+" pefs addchecklist [-i inputfile] [-o outputfile] filesystem\n"
);
exit(PEFS_ERR_USAGE);
}
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Fri May 25 16:26:06 2012 (r236400)
@@ -94,7 +94,7 @@
int pefs_key_decrypt(struct pefs_xkeyenc *xe,
const struct pefs_xkey *xk_parent);
uintmax_t pefs_keyid_as_int(char *keyid);
-int pefs_create_checksum_file(FILE *fpin, char *fsroot, const char *algo);
+int pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path, const char *algo);
int pefs_create_checklist(FILE *fpin, int fdout, char *fsroot, char *fromfsroot);
const char * pefs_alg_name(struct pefs_xkey *xk);
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Fri May 25 16:26:06 2012 (r236400)
@@ -48,9 +48,16 @@
char pxk_key[PEFS_KEY_SIZE];
};
+/*
+ * XXXgpf: [TODO] gleb says:
+ Adding 'x' to mark
+ it as exported to userspace will also be wise. So it's better be
+ pefs_xnamecsum or pefs_xname_csum.
+ */
struct pefs_namemac {
- uint32_t pnm_namelen;
uint64_t pnm_csum;
+ uint32_t pnm_namelen;
+ /* XXXgpf: should probably be MAXNAMLEN */
char pnm_filename[MAXPATHLEN];
};
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Fri May 25 16:26:06 2012 (r236400)
@@ -2471,15 +2471,25 @@
pefs_flushkey(mp, td, PEFS_FLUSHKEY_ALL, NULL);
break;
case PEFS_GETNAMEMAC:
- if (vp->v_type != VDIR)
- panic("pefs_ioctl: PEFS_GETNAMEMAC vp is not a directory\n");
+ /* XXXgpf: should I change printf to PEFSDEBUG or something else? */
+ if (vp->v_type != VDIR) {
+ printf("pefs_ioctl: PEFS_GETNAMEMAC vp is not a directory\n");
+ error = EINVAL;
+ break;
+ }
if (strnlen(namemac->pnm_filename, sizeof(namemac->pnm_filename)) !=
- namemac->pnm_namelen)
- panic("pefs_ioctl: PEFS_GETNAMEMAC incorrect pnm_namelen\n");
+ namemac->pnm_namelen) {
+ printf("pefs_ioctl: PEFS_GETNAMEMAC incorrect pnm_namelen %d\n", namemac->pnm_namelen);
+ error = EINVAL;
+ break;
+ }
- if (strchr(namemac->pnm_filename, '/') != NULL)
- panic("pefs_ioctl: PEFS_GETNAMEMAC pnm_filename contains '/'\n");
+ if (strchr(namemac->pnm_filename, '/') != NULL) {
+ printf("pefs_ioctl: PEFS_GETNAMEMAC pnm_filename contains '/'\n");
+ error = EINVAL;
+ break;
+ }
vn_lock(vp, LK_EXCLUSIVE);
pefs_enccn_init(&enccn);
@@ -2500,6 +2510,7 @@
enc_len = enccn.pec_cn.cn_namelen;
if (enc[0] != '.' || enc_len <= 1) {
+ pefs_enccn_free(&enccn);
error = EINVAL;
break;
}
Modified: soc2012/gpf/pefs_kmod/sys/modules/pefs/Makefile
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/modules/pefs/Makefile Fri May 25 15:16:40 2012 (r236399)
+++ soc2012/gpf/pefs_kmod/sys/modules/pefs/Makefile Fri May 25 16:26:06 2012 (r236400)
@@ -23,4 +23,3 @@
SRCS+= hmac_sha512.c
.include <bsd.kmod.mk>
-
More information about the svn-soc-all
mailing list