socsvn commit: r239244 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Tue Jul 10 17:32:54 UTC 2012
Author: gpf
Date: Tue Jul 10 17:32:52 2012
New Revision: 239244
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239244
Log:
take care of dynamic memory
- free RB tree kept for hardlinks
- new allocation function for struct file_header. moving all initialization
code to this function really helps.
- new function to free struct file_header
- free global file header tailq
- also fixing a few leaks in case of error here and there.
Modified:
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Tue Jul 10 15:02:29 2012 (r239243)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Tue Jul 10 17:32:52 2012 (r239244)
@@ -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
@@ -199,9 +199,6 @@
size_t buf_len;
struct checksum *csp;
- TAILQ_INIT(&(fhp->checksums));
- fhp->nhashes = 0;
-
if ((flags & PEFS_UNMOUNTED) != 0 || (flags & PEFS_NOKEY) != 0) {
buf = fhp->target_path;
buf_len = strnlen(fhp->target_path, MAXPATHLEN + 1);
@@ -272,8 +269,6 @@
if (fhp->target_path != NULL)
return (pefs_compute_symlink_checksum(fhp, md, hash_len, flags));
- TAILQ_INIT(&(fhp->checksums));
-
/* XXXgpf: what happens if file size > 2^64? */
if (fstat(fhp->fd, &sb) != 0) {
warn("cannot stat file %s", fhp->path);
@@ -295,7 +290,6 @@
}
}
- fhp->nhashes = 0;
offset = 0;
xsct.pxsct_offset = 0;
while (resid > 0) {
@@ -339,12 +333,14 @@
csp = malloc(sizeof(struct checksum));
if (csp == NULL) {
pefs_warn("memory allocation error");
+ EVP_MD_CTX_cleanup(&mdctx);
return (PEFS_ERR_SYS);
}
csp->hash = malloc(hash_len);
if (csp->hash == NULL) {
pefs_warn("memory allocation error");
free(csp);
+ EVP_MD_CTX_cleanup(&mdctx);
return (PEFS_ERR_SYS);
}
@@ -436,29 +432,62 @@
return (0);
}
+static struct file_header *
+pefs_allocate_file_header(void)
+{
+ struct file_header *fhp;
+
+ fhp = malloc(sizeof(struct file_header));
+ if (fhp == NULL) {
+ pefs_warn("memory allocation error");
+ return (NULL);
+ }
+
+ fhp->nhashes = 0;
+ fhp->offset_to_checksums = 0;
+ fhp->file_id = 0;
+ fhp->fd = -1;
+ fhp->pfd = -1;
+ fhp->found = 0;
+
+ fhp->target_path = NULL;
+
+ fhp->path[0] = '\0';
+ fhp->dirpath[0] = '\0';
+ fhp->filename[0] = '\0';
+
+ TAILQ_INIT(&(fhp->checksums));
+
+ return (fhp);
+}
+
+static void
+pefs_free_file_header(struct file_header *fhp)
+{
+ struct checksum *csp, *tcsp;
+ if (fhp != NULL) {
+ TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) {
+ TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries);
+ if (csp->hash != NULL)
+ free(csp->hash);
+ free(csp);
+ }
+ if (fhp->target_path != NULL)
+ free(fhp->target_path);
+ free(fhp);
+ }
+}
+
static void
pefs_free_hash_table(struct cuckoo_hash_table *chtp)
{
struct bucket *bp;
- struct file_header *fhp;
- struct checksum *csp, *tcsp;
uint32_t i;
if (chtp->buckets1 != NULL) {
for (i = 0; i < chtp->size; i++) {
bp = &chtp->buckets1[i];
- fhp = bp->fhp;
- if (fhp != NULL) {
- TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) {
- TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries);
- if (csp->hash != NULL)
- free(csp->hash);
- free(csp);
- }
- if (fhp->target_path != NULL)
- free(fhp->target_path);
- free(fhp);
- }
+ pefs_free_file_header(bp->fhp);
}
free(chtp->buckets1);
}
@@ -466,23 +495,23 @@
if (chtp->buckets2 != NULL) {
for (i = 0; i < chtp->size; i++) {
bp = &chtp->buckets2[i];
- fhp = bp->fhp;
- if (fhp != NULL) {
- TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) {
- TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries);
- if (csp->hash != NULL)
- free(csp->hash);
- free(csp);
- }
- if (fhp->target_path != NULL)
- free(fhp->target_path);
- free(fhp);
- }
+ pefs_free_file_header(bp->fhp);
}
free(chtp->buckets2);
}
}
+static void
+pefs_free_file_header_tail(struct file_header_head *fh_headp)
+{
+ struct file_header *fhp, *tfhp;
+
+ TAILQ_FOREACH_SAFE(fhp, fh_headp, file_header_entries, tfhp) {
+ TAILQ_REMOVE(fh_headp, fhp, file_header_entries);
+ pefs_free_file_header(fhp);
+ }
+}
+
static uint32_t
pefs_hash1(struct cuckoo_hash_table *chtp, struct file_header *fhp)
{
@@ -830,6 +859,18 @@
return 0;
}
+static void
+pefs_rb_free(struct hardlink_head *hlc_headp)
+{
+ struct hardlink_counter *cur, *next;
+
+ for (cur = RB_MIN(hardlink_head, hlc_headp); cur != NULL; cur = next) {
+ next = RB_NEXT(hardlink_head, hlc_headp, cur);
+ RB_REMOVE(hardlink_head, hlc_headp, cur);
+ free(cur);
+ }
+}
+
/* open a file and perform various semantic checks on it */
static int
pefs_open_semantic_checks(struct file_header *fhp, struct statfs *fsp, struct hardlink_head *hlc_headp, int flags)
@@ -842,10 +883,6 @@
size_t target_path_size;
int nchars;
- /* initialize file descriptors in case error occurs */
- fhp->fd = -1;
- fhp->pfd = -1;
-
/* retrieve dirpath & filename */
strlcpy(dirbuf, fhp->path, sizeof(dirbuf));
strlcpy(namebuf, fhp->path, sizeof(namebuf));
@@ -873,8 +910,6 @@
}
if (S_ISLNK(sb.st_mode) != 0) {
- fhp->target_path = NULL;
-
fhp->pfd = open(fhp->dirpath, O_RDONLY);
if (fhp->pfd < 0) {
warn("cannot open %s", fhp->dirpath);
@@ -931,8 +966,6 @@
}
return (0);
}
- else
- fhp->target_path = NULL;
fhp->fd = open(fhp->path, O_RDONLY | O_NOFOLLOW);
if (fhp->fd < 0) {
@@ -997,9 +1030,8 @@
buf[strnlen(buf, sizeof(buf)) - 1] = '\0';
dprintf(("\nnext file entry=%s!\n", buf));
- fhp = malloc(sizeof(struct file_header));
+ fhp = pefs_allocate_file_header();
if (fhp == NULL) {
- warn("memory allocation error");
*error = PEFS_ERR_SYS;
return (NULL);
}
@@ -1058,18 +1090,21 @@
error = pefs_open_semantic_checks(fhp, &fs, &hlc_head, 0);
if (error != 0) {
pefs_close_file(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
error = pefs_get_file_id(fhp, 0);
if (error != 0) {
pefs_close_file(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
error = pefs_compute_file_checksums(fhp, md, hash_len, 0);
if (error != 0) {
pefs_close_file(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
@@ -1083,7 +1118,7 @@
pefs_rb_print(&hlc_head);
pefs_rb_warn(&hlc_head);
- /* XXXgpf: [TODO] rb_free */
+ pefs_rb_free(&hlc_head);
error = pefs_allocate_hash_table(chtp, nfiles, PEFS_EXTEND);
if (error != 0)
@@ -1511,18 +1546,16 @@
int error;
//dprintf(("bucket offset = %d\n", *buckets_offset));
- fhp = malloc(sizeof(struct file_header));
- if (fhp == NULL) {
- pefs_warn("memory allocation error");
+ fhp = pefs_allocate_file_header();
+ if (fhp == NULL)
return (PEFS_ERR_SYS);
- }
error = pefs_read_file_header(fdin, fhp, buckets_offset);
if (error != 0)
return (error);
if (fhp->nhashes == 0) {
- free(fhp);
+ pefs_free_file_header(fhp);
fhp = NULL;
}
bp->fhp = fhp;
@@ -1556,9 +1589,7 @@
TAILQ_INSERT_TAIL(&(fhp->checksums), csp, checksum_entries);
}
-/*
- * XXXgpf: [TODO] comments
- */
+/* Create in memory checksum database by reading .pefs.checksum file. */
static int
pefs_read_checksum_file(int fdin, struct checksum_file_header *cfhp, struct cuckoo_hash_table *chtp)
{
@@ -1579,10 +1610,7 @@
fhp = bp->fhp;
if (fhp != NULL) {
- TAILQ_INIT(&(fhp->checksums));
hashes_offset = fhp->offset_to_checksums;
- fhp->found = 0;
- fhp->target_path = NULL;
for (k = 0; k < fhp->nhashes; k++) {
csp = malloc(sizeof(struct checksum));
@@ -1613,10 +1641,7 @@
fhp = bp->fhp;
if (fhp != NULL) {
- TAILQ_INIT(&(fhp->checksums));
hashes_offset = fhp->offset_to_checksums;
- fhp->found = 0;
- fhp->target_path = NULL;
for (k = 0; k < fhp->nhashes; k++) {
csp = malloc(sizeof(struct checksum));
@@ -1728,9 +1753,8 @@
/* FALLTHROUGH */
case DT_REG:
case DT_LNK:
- fhp = malloc(sizeof(struct file_header));
+ fhp = pefs_allocate_file_header();
if (fhp == NULL) {
- warn("memory allocation error");
closedir(dirp);
return (PEFS_ERR_SYS);
}
@@ -1739,7 +1763,7 @@
error = pefs_open_semantic_checks(fhp, fsp, NULL, flags);
if (error != 0) {
closedir(dirp);
- free(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
@@ -1747,14 +1771,14 @@
if (error != 0) {
closedir(dirp);
pefs_close_file(fhp);
- free(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
indexfhp = pefs_cuckoo_lookup(chtp, fhp);
if (indexfhp == NULL) {
pefs_close_file(fhp);
- free(fhp);
+ pefs_free_file_header(fhp);
break;
}
indexfhp->found = 1;
@@ -1763,7 +1787,7 @@
if (error != 0) {
closedir(dirp);
pefs_close_file(fhp);
- free(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
@@ -1773,7 +1797,7 @@
warn("cannot stat file %s", fhp->path);
closedir(dirp);
pefs_close_file(fhp);
- free(fhp);
+ pefs_free_file_header(fhp);
return (PEFS_ERR_SYS);
}
@@ -1781,7 +1805,7 @@
if (error != 0) {
closedir(dirp);
pefs_close_file(fhp);
- free(fhp);
+ pefs_free_file_header(fhp);
return (error);
}
@@ -1916,8 +1940,8 @@
out:
pefs_free_hash_table(&cht);
- /* XXXgpf: [TODO] rb_free */
- /* XXXgpf: [TODO] fh_free */
+ 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 Tue Jul 10 15:02:29 2012 (r239243)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Tue Jul 10 17:32:52 2012 (r239244)
@@ -1020,8 +1020,11 @@
* .pefs.checksum is created under $PWD. path should be a directory,
* outside of target pefs filesystem.
*
- * When $command is run, filesystem must be mounted with pefs, and
- * user must have supplied the key.
+ * When $command is run, filesystem must be mounted with pefs, and
+ * user must have supplied the necessary key(s).
+ *
+ * [TODO] a flag that allows $command to turn on immutable flags for
+ * every file that requires integrity checking.
*/
static int
pefs_addchecksum(int argc, char *argv[])
@@ -1120,8 +1123,7 @@
* By default, pefs will assume that filesystem is mounted and user
* has provided key.
*
- * Verifying the integrity of the checksum file itself via a signature
- * remains a major TODO.
+ * [TODO] Verify the integrity of the checksum file itself via a signature.
*/
static int
pefs_verify(int argc, char *argv[])
@@ -1172,6 +1174,10 @@
if ((flags & PEFS_UNMOUNTED) == 0)
initfsroot(argc, argv, 0, fsroot, sizeof(fsroot));
else {
+ /*
+ * XXXgpf: should i also check that fsroot path belongs to
+ * a non pefs filesystem?
+ */
strlcpy(fsroot, argv[0], sizeof(fsroot));
if (stat(fsroot, &sb) != 0) {
warn("cannot stat fs root: %s", fsroot);
@@ -1196,6 +1202,8 @@
return (error);
}
+/* XXXgpf: [TODO] a command that returns the file id of a file (name MAC) */
+
static void
pefs_usage_alg(void)
{
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Tue Jul 10 15:02:29 2012 (r239243)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Tue Jul 10 17:32:52 2012 (r239244)
@@ -79,6 +79,10 @@
start = &(pcs->pcs_table1[pos * PEFS_HT_CELL_SIZE]);
p = start;
+ /*
+ * XXXgpf: [TODO] move the reading of a checksum index entry to a different function.
+ * Also, perhaps a macro to tell if an index entry is empty or not (nhashes == 0).
+ */
memcpy(&(target_pcie.pcie_nhashes), p, sizeof(target_pcie.pcie_nhashes));
target_pcie.pcie_nhashes = le32toh(target_pcie.pcie_nhashes);
if (target_pcie.pcie_nhashes != 0) {
More information about the svn-soc-all
mailing list