Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jul 2012 17:06:49 +0000
From:      gpf@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239557 - soc2012/gpf/pefs_kmod/sbin/pefs
Message-ID:  <20120718170649.1052F1065670@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gpf
Date: Wed Jul 18 17:06:48 2012
New Revision: 239557
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239557

Log:
  require that all files that need integrity checking should have schg flag
  set. provide an option to set the flags during `addchecksum` action, if
  they are not already set. ([-f] option)
  `verify` action checks for this as well.
  
  same checks should be performed in kernel land when a vnode is looked up
  in our index tables.
  

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

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Wed Jul 18 16:13:03 2012	(r239556)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Wed Jul 18 17:06:48 2012	(r239557)
@@ -57,7 +57,7 @@
 
 #include "pefs_ctl.h"
 
-//#define PEFS_INTEGRITY_DEBUG
+#define PEFS_INTEGRITY_DEBUG
 #if defined (PEFS_INTEGRITY_DEBUG)
 #define dprintf(a)		printf a
 #else
@@ -188,10 +188,14 @@
 static void
 pefs_close_file(struct file_header *fhp)
 {
-	if (fhp->fd >= 0)
+	if (fhp->fd >= 0) {
 		close(fhp->fd);
-	if (fhp->pfd >= 0)
+		fhp->fd = -1;
+	}
+	if (fhp->pfd >= 0) {
 		close(fhp->pfd);
+		fhp->pfd = -1;
+	}
 }
 
 static int
@@ -476,7 +480,7 @@
 {
 	struct checksum *csp, *tcsp;
 	if (fhp != NULL) {
-		/* XXXgpf: [TODO] should probably call pefs_close_file() at this point */
+		pefs_close_file(fhp);
 		TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) {
 			TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries);
 			if (csp->hash != NULL)
@@ -896,7 +900,7 @@
 	struct statfs this_fs;
 	char *dirnamep, *namep;
 	size_t target_path_size;
-	int nchars;
+	int error, nchars;
 
 	/* retrieve dirpath & filename */
 	strlcpy(dirbuf, fhp->path, sizeof(dirbuf));
@@ -917,7 +921,7 @@
 	}
 	strlcpy(fhp->filename, namep, sizeof(fhp->filename));
 
-	dprintf(("path = %s!\ndirname = %s!\nbasename =%s!\n", fhp->path,
+	dprintf(("path = %s!\ndirname = %s!\nbasename = %s!\n", fhp->path,
 			fhp->dirpath, fhp->filename));
 
 	if (lstat(fhp->path, &sb) != 0) {
@@ -925,6 +929,13 @@
 		return (PEFS_ERR_SYS);
 	}
 
+	if ((sb.st_flags & SF_IMMUTABLE) == 0 &&
+		(flags & PEFS_SETIMMUTABLE) == 0 &&
+		(flags & PEFS_VERIFY) == 0) {
+		pefs_warn("file %s does not have schg flag", fhp->path);
+		return (PEFS_ERR_SYS);
+	}
+
 	if (S_ISLNK(sb.st_mode) != 0) {
 		fhp->pfd = open(fhp->dirpath, O_RDONLY);
 		if (fhp->pfd < 0) {
@@ -932,6 +943,16 @@
 			return (PEFS_ERR_IO);
 		}
 
+		if ((sb.st_flags & SF_IMMUTABLE) == 0 &&
+			(flags & PEFS_SETIMMUTABLE) != 0) {
+			dprintf(("setting immutable flag %s\n", fhp->path));
+			error = lchflags(fhp->path, SF_IMMUTABLE);
+			if (error != 0) {
+				warn("cannot set schg flag to file %s", fhp->path);
+				return (PEFS_ERR_SYS);
+			}
+		}
+
 		nchars = readlink(fhp->path, sbuf, sizeof(sbuf));
 		if (nchars == -1) {
 			warn("readlink failed: %s", fhp->path);
@@ -1007,6 +1028,16 @@
 		return (PEFS_ERR_INVALID);
 	}
 
+	if ((sb.st_flags & SF_IMMUTABLE) == 0 &&
+		(flags & PEFS_SETIMMUTABLE) != 0) {
+		dprintf(("setting immutable flag %s\n", fhp->path));
+		error = fchflags(fhp->fd, SF_IMMUTABLE);
+		if (error != 0) {
+			warn("cannot set schg flag to file %s", fhp->path);
+			return (PEFS_ERR_SYS);
+		}
+	}
+
 	if ((flags & PEFS_UNMOUNTED) == 0) {
 		if (fstatfs(fhp->fd, &this_fs) == -1) {
 			pefs_warn("statfs failed: %s: %s", fhp->path, strerror(errno));
@@ -1089,7 +1120,7 @@
  */
 static int
 pefs_create_in_memory_db(FILE *fpin, const EVP_MD *md, uint8_t hash_len,
-	struct cuckoo_hash_table *chtp, char *fsroot)
+	struct cuckoo_hash_table *chtp, char *fsroot, int flags)
 {
 	struct statfs fs;
 	struct file_header_head fh_head;
@@ -1107,23 +1138,20 @@
 	TAILQ_INIT(&fh_head);
 	RB_INIT(&hlc_head);
 	while((fhp = pefs_next_file(fpin, &error, &nfiles)) != NULL) {
-		error = pefs_open_semantic_checks(fhp, &fs, &hlc_head, 0);
+		error = pefs_open_semantic_checks(fhp, &fs, &hlc_head, flags);
 		if (error != 0) {
-			pefs_close_file(fhp);
 			pefs_free_file_header(fhp);
 			return (error);
 		}
 
-		error = pefs_get_file_id(fhp, 0);
+		error = pefs_get_file_id(fhp, flags);
 		if (error != 0) {
-			pefs_close_file(fhp);
 			pefs_free_file_header(fhp);
 			return (error);
 		}
 
-		error = pefs_compute_file_checksums(fhp, md, hash_len, 0);
+		error = pefs_compute_file_checksums(fhp, md, hash_len, flags);
 		if (error != 0) {
-			pefs_close_file(fhp);
 			pefs_free_file_header(fhp);
 			return (error);
 		}
@@ -1440,7 +1468,7 @@
  */
 int
 pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path,
-	const char *algo)
+	const char *algo, int flags)
 {
 	struct cuckoo_hash_table checksum_hash_table;
 	struct checksum_file_header cfh;
@@ -1464,7 +1492,7 @@
 		goto out;
 
 	error = pefs_create_in_memory_db(fpin, md, hash_len,
-		&checksum_hash_table, fsroot);
+		&checksum_hash_table, fsroot, flags);
 	if (error != 0)
 		goto out;
 
@@ -1819,14 +1847,12 @@
 				error = pefs_get_file_id(fhp, flags);
 				if (error != 0) {
 					closedir(dirp);
-					pefs_close_file(fhp);
 					pefs_free_file_header(fhp);
 					return (error);
 				}
 
 				indexfhp = pefs_cuckoo_lookup(chtp, fhp);
 				if (indexfhp == NULL) {
-					pefs_close_file(fhp);
 					pefs_free_file_header(fhp);
 					break;
 				}
@@ -1835,17 +1861,21 @@
 				error = pefs_compute_file_checksums(fhp, md, hash_len, flags);
 				if (error != 0) {
 					closedir(dirp);
-					pefs_close_file(fhp);
 					pefs_free_file_header(fhp);
 					return (error);
 				}
 
-				/* get sb for pefs_rb_insert */
 				error = lstat(fhp->path, &sb);
 				if (error != 0) {
 					warn("cannot stat file %s", fhp->path);
 					closedir(dirp);
-					pefs_close_file(fhp);
+					pefs_free_file_header(fhp);
+					return (PEFS_ERR_SYS);
+				}
+
+				if ((sb.st_flags & SF_IMMUTABLE) == 0) {
+					pefs_warn("file %s does not have schg flag", fhp->path);
+					closedir(dirp);
 					pefs_free_file_header(fhp);
 					return (PEFS_ERR_SYS);
 				}
@@ -1853,7 +1883,6 @@
 				error = pefs_rb_insert(hlc_headp, fhp, &sb);
 				if (error != 0) {
 					closedir(dirp);
-					pefs_close_file(fhp);
 					pefs_free_file_header(fhp);
 					return (error);
 				}
@@ -1994,6 +2023,7 @@
 	pefs_free_hash_table(&cht);
 	pefs_rb_free(&hlc_head);
 	pefs_free_file_header_tail(&fh_head);
+
 	return (error);
 }
 

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Wed Jul 18 16:13:03 2012	(r239556)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Wed Jul 18 17:06:48 2012	(r239557)
@@ -1004,7 +1004,7 @@
 /*
  * XXXgpf: Instead of a man page entry:
  *
- * pefs addchecksum [-a algo] [-i inputfile] [-p path] filesystem
+ * pefs addchecksum [-f] [-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
@@ -1021,6 +1021,9 @@
  * .pefs.checksum is created under $PWD. path should be a directory,
  * outside of target pefs filesystem.
  *
+ * -f symbolizes that $command should set immutable flag schg for every file
+ * in inputlist if the flag is not already set.
+ *
  * When $command is run, filesystem must be mounted with pefs, and
  * user must have supplied the necessary key(s).
  *
@@ -1034,16 +1037,17 @@
 	char csm_path[MAXPATHLEN];
 	struct stat sb;
 	FILE *fpin;
-	int error, i, j;
+	int error, flags, i, j;
 	const char *algo;
 
+	flags = 0;
 	fpin = stdin;
 	/* 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:p:")) != -1)
+	while ((i = getopt(argc, argv, "fa:i:p:")) != -1)
 		switch(i) {
 		case 'a':
 			for (j=0; j < PEFS_SUPPORTED_DIGESTS; j++)
@@ -1058,6 +1062,9 @@
 				goto out;
 			}
 			break;
+		case 'f':
+			flags|= PEFS_SETIMMUTABLE;
+			break;
 		case 'i':
 			fpin = fopen(optarg, "r");
 			if (fpin == NULL) {
@@ -1093,7 +1100,7 @@
 
 	initfsroot(argc, argv, 0, fsroot, sizeof(fsroot));
 
-	error = pefs_create_checksum_file(fpin, fsroot, csm_path, algo);
+	error = pefs_create_checksum_file(fpin, fsroot, csm_path, algo, flags);
 
 out:
 	if (fpin != NULL)
@@ -1133,7 +1140,7 @@
 	char fsroot[MAXPATHLEN];
 	int error, fdin, flags, i;
 
-	flags = 0;
+	flags = PEFS_VERIFY;
 	while ((i = getopt(argc, argv, "nu")) != -1)
 		switch(i) {
 		case 'n':
@@ -1230,7 +1237,7 @@
 "	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] [-p checksumpath] filesystem\n"
+"	pefs addchecksum [-f] [-a algo] [-i inputfile] [-p checksumpath] filesystem\n"
 "	pefs verify [-n/u] [checksumpath 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	Wed Jul 18 16:13:03 2012	(r239556)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h	Wed Jul 18 17:06:48 2012	(r239557)
@@ -46,6 +46,8 @@
 
 #define PEFS_NOKEY				0x0001
 #define PEFS_UNMOUNTED			0x0002
+#define PEFS_SETIMMUTABLE		0x0004
+#define PEFS_VERIFY				0x0010
 
 #define	PEFS_KEYCONF_ALG_IND		0
 #define	PEFS_KEYCONF_ITERATIONS_IND	1
@@ -99,7 +101,7 @@
 	    const struct pefs_xkey *xk_parent);
 uintmax_t	pefs_keyid_as_int(char *keyid);
 int pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path,
-		const char *algo);
+		const char *algo, int flags);
 int pefs_verify_checksum(int fdin, char *fsroot, int flags);
 
 int	pefs_name_pton(char const *src, size_t srclen, u_char *target,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120718170649.1052F1065670>