From owner-svn-soc-all@FreeBSD.ORG Wed Jul 18 17:06:51 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 1052F1065670 for ; Wed, 18 Jul 2012 17:06:49 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Wed, 18 Jul 2012 17:06:49 +0000 Date: Wed, 18 Jul 2012 17:06:49 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120718170649.1052F1065670@hub.freebsd.org> Cc: Subject: socsvn commit: r239557 - soc2012/gpf/pefs_kmod/sbin/pefs X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jul 2012 17:06:51 -0000 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,