Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Nov 2012 17:05:17 GMT
From:      Brooks Davis <brooks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 219862 for review
Message-ID:  <201211291705.qATH5Htj038200@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@219862?ac=10

Change 219862 by brooks@brooks_zenith on 2012/11/29 17:04:29

	Add a new magic_load_buffers() function to load compiled
	magic data without filesystem access.  This will make fork
	and exec capsicum sandboxes slightly cheaper and make cheri
	sandboxes practical.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/contrib/file/apprentice.c#3 edit
.. //depot/projects/ctsrd/cheribsd/src/contrib/file/file.h#3 edit
.. //depot/projects/ctsrd/cheribsd/src/contrib/file/magic.c#3 edit
.. //depot/projects/ctsrd/cheribsd/src/contrib/file/magic.h#3 edit

Differences ...

==== //depot/projects/ctsrd/cheribsd/src/contrib/file/apprentice.c#3 (text+ko) ====

@@ -106,11 +106,15 @@
 #endif
 private char *mkdbname(struct magic_set *, const char *, int);
 #ifndef COMPILE_ONLY
+private int check_buffer(struct magic_set *, struct magic **, uint32_t *,
+    const char *);
 private int apprentice_map(struct magic_set *, struct magic **, uint32_t *,
     const char *);
 #endif
 private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *,
     const char *);
+private int mlist_insert(struct magic_set *, struct mlist *, struct magic *,
+    uint32_t, int);
 private int check_format_type(const char *, int);
 private int check_format(struct magic_set *, struct magic *);
 private int get_op(char);
@@ -265,9 +269,6 @@
 {
 	struct magic *magic = NULL;
 	uint32_t nmagic = 0;
-#ifndef COMPILE_ONLY
-	struct mlist *ml;
-#endif
 	int rv = -1;
 #ifndef COMPILE_ONLY
 	int mapped;
@@ -305,6 +306,25 @@
 		return -1;
 	}
 
+	if (mlist_insert(ms, mlist, magic, nmagic, mapped) != 0)
+		return -1;
+
+	if (action == FILE_LIST) {
+		printf("Binary patterns:\n");
+		apprentice_list(mlist, BINTEST);
+		printf("Text patterns:\n");
+		apprentice_list(mlist, TEXTTEST);
+	}
+#endif /* COMPILE_ONLY */
+	return 0;
+}
+
+private int
+mlist_insert(struct magic_set *ms, struct mlist *mlist, struct magic *magic,
+    uint32_t nmagic, int mapped)
+{
+	struct mlist *ml;
+
 	if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) {
 		file_delmagic(magic, mapped, nmagic);
 		file_oomem(ms, sizeof(*ml));
@@ -320,13 +340,6 @@
 	ml->next = mlist;
 	mlist->prev = ml;
 
-	if (action == FILE_LIST) {
-		printf("Binary patterns:\n");
-		apprentice_list(mlist, BINTEST);
-		printf("Text patterns:\n");
-		apprentice_list(mlist, TEXTTEST);
-	}
-#endif /* COMPILE_ONLY */
 	return 0;
 }
 
@@ -336,6 +349,8 @@
 	if (p == NULL)
 		return;
 	switch (type) {
+	case 3:
+		break;
 	case 2:
 #ifdef QUICK
 		p--;
@@ -357,6 +372,42 @@
 	}
 }
 
+#ifndef COMPILE_ONLY
+/* void **bufs: an array of compiled magic files */
+protected struct mlist *
+file_buffer_apprentice(struct magic_set *ms, struct magic **bufs,
+    size_t *sizes, int nbufs)
+{
+	int i, mapped;
+	uint32_t nmagic;
+	struct magic *magic;
+	struct mlist *mlist;
+
+	if (nbufs < 1)
+		return NULL;
+
+	if ((mlist = CAST(struct mlist *, malloc(sizeof(*mlist)))) == NULL) {
+		file_oomem(ms, sizeof(*mlist));
+		return NULL;
+	}
+	mlist->next = mlist->prev = mlist;
+
+	for (i = 0; i < nbufs; i++) {
+		magic = bufs[i];
+		nmagic = (uint32_t)(sizes[i] / sizeof(struct magic));
+		if (check_buffer(ms, &magic, &nmagic, "private buffer") != 0)
+			goto error;
+		if (mlist_insert(ms, mlist, magic, nmagic, mapped) != 0)
+			goto error;
+	}
+
+	return mlist;
+error:
+	file_free_mlist(mlist);
+	return NULL;
+}
+#endif
+
 /* const char *fn: list of magic files and directories */
 protected struct mlist *
 file_apprentice(struct magic_set *ms, const char *fn, int action)
@@ -2205,6 +2256,42 @@
 }
 
 #ifndef COMPILE_ONLY
+private int
+check_buffer(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
+    const char *dbname)
+{
+	uint32_t *ptr;
+	uint32_t version;
+	int needsbyteswap;
+
+	ptr = (uint32_t *)(void *)*magicp;
+	if (*ptr != MAGICNO) {
+		if (swap4(*ptr) != MAGICNO) {
+			file_error(ms, 0, "bad magic in `%s'", dbname);
+			return -1;
+		}
+		needsbyteswap = 1;
+	} else
+		needsbyteswap = 0;
+	if (needsbyteswap)
+		version = swap4(ptr[1]);
+	else
+		version = ptr[1];
+	if (version != VERSIONNO) {
+		file_error(ms, 0, "File %s supports only version %d magic "
+		    "files. `%s' is version %d", VERSION,
+		    VERSIONNO, dbname, version);
+		return -1;
+	}
+	if (*nmagicp > 0)
+		(*nmagicp)--;
+	(*magicp)++;
+	if (needsbyteswap)
+		byteswap(*magicp, *nmagicp);
+
+	return 0;
+}
+
 /*
  * handle a compiled file.
  */
@@ -2214,9 +2301,6 @@
 {
 	int fd;
 	struct stat st;
-	uint32_t *ptr;
-	uint32_t version;
-	int needsbyteswap;
 	char *dbname = NULL;
 	void *mm = NULL;
 
@@ -2254,34 +2338,14 @@
 	}
 #define RET	1
 #endif
-	*magicp = CAST(struct magic *, mm);
 	(void)close(fd);
 	fd = -1;
-	ptr = (uint32_t *)(void *)*magicp;
-	if (*ptr != MAGICNO) {
-		if (swap4(*ptr) != MAGICNO) {
-			file_error(ms, 0, "bad magic in `%s'", dbname);
-			goto error1;
-		}
-		needsbyteswap = 1;
-	} else
-		needsbyteswap = 0;
-	if (needsbyteswap)
-		version = swap4(ptr[1]);
-	else
-		version = ptr[1];
-	if (version != VERSIONNO) {
-		file_error(ms, 0, "File %s supports only version %d magic "
-		    "files. `%s' is version %d", VERSION,
-		    VERSIONNO, dbname, version);
+	*magicp = CAST(struct magic *, mm);
+	*nmagicp = (uint32_t)(st.st_size / sizeof(struct magic));
+
+	if (check_buffer(ms, magicp, nmagicp, dbname) != 0)
 		goto error1;
-	}
-	*nmagicp = (uint32_t)(st.st_size / sizeof(struct magic));
-	if (*nmagicp > 0)
-		(*nmagicp)--;
-	(*magicp)++;
-	if (needsbyteswap)
-		byteswap(*magicp, *nmagicp);
+
 	free(dbname);
 	return RET;
 

==== //depot/projects/ctsrd/cheribsd/src/contrib/file/file.h#3 (text+ko) ====

@@ -331,7 +331,8 @@
 	uint32_t nmagic;			/* number of entries in array */
 	int mapped;  /* allocation type: 0 => apprentice_file
 		      *                  1 => apprentice_map + malloc
-		      *                  2 => apprentice_map + mmap */
+		      *                  2 => apprentice_map + mmap
+		      *                  3 => caller owned */
 	struct mlist *next, *prev;
 };
 
@@ -415,7 +416,10 @@
 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
     int, int);
+protected struct mlist *file_buffer_apprentice(struct magic_set *,
+    struct magic **, size_t *, int);
 protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
+protected void file_free_mlist(struct mlist *);
 protected uint64_t file_signextend(struct magic_set *, struct magic *,
     uint64_t);
 protected void file_delmagic(struct magic *, int type, size_t entries);

==== //depot/projects/ctsrd/cheribsd/src/contrib/file/magic.c#3 (text+ko) ====

@@ -71,7 +71,6 @@
 #endif
 #endif
 
-private void free_mlist(struct mlist *);
 #ifndef COMPILE_ONLY
 private void close_and_restore(const struct magic_set *, const char *, int,
     const struct stat *);
@@ -239,8 +238,8 @@
 	return NULL;
 }
 
-private void
-free_mlist(struct mlist *mlist)
+protected void
+file_free_mlist(struct mlist *mlist)
 {
 	struct mlist *ml;
 
@@ -280,7 +279,7 @@
 public void
 magic_close(struct magic_set *ms)
 {
-	free_mlist(ms->mlist);
+	file_free_mlist(ms->mlist);
 	free(ms->o.pbuf);
 	free(ms->o.buf);
 	free(ms->c.li);
@@ -295,18 +294,36 @@
 {
 	struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD);
 	if (ml) {
-		free_mlist(ms->mlist);
+		file_free_mlist(ms->mlist);
+		ms->mlist = ml;
+		return 0;
+	}
+	return -1;
+}
+
+#ifndef COMPILE_ONLY
+/*
+ * Install a set of compiled magic buffers.
+ */
+public int
+magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes, int nbufs)
+{
+	struct mlist *ml = file_buffer_apprentice(ms, (struct magic **)bufs,
+	    sizes, nbufs);
+	if (ml) {
+		file_free_mlist(ms->mlist);
 		ms->mlist = ml;
 		return 0;
 	}
 	return -1;
 }
+#endif
 
 public int
 magic_compile(struct magic_set *ms, const char *magicfile)
 {
 	struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE);
-	free_mlist(ml);
+	file_free_mlist(ml);
 	return ml ? 0 : -1;
 }
 
@@ -314,7 +331,7 @@
 magic_check(struct magic_set *ms, const char *magicfile)
 {
 	struct mlist *ml = file_apprentice(ms, magicfile, FILE_CHECK);
-	free_mlist(ml);
+	file_free_mlist(ml);
 	return ml ? 0 : -1;
 }
 
@@ -322,7 +339,7 @@
 magic_list(struct magic_set *ms, const char *magicfile)
 {
 	struct mlist *ml = file_apprentice(ms, magicfile, FILE_LIST);
-	free_mlist(ml);
+	file_free_mlist(ml);
 	return ml ? 0 : -1;
 }
 

==== //depot/projects/ctsrd/cheribsd/src/contrib/file/magic.h#3 (text+ko) ====

@@ -92,6 +92,8 @@
 int magic_setflags(magic_t, int);
 
 int magic_load(magic_t, const char *);
+int magic_load_buffers(struct magic_set *, void **, size_t *, int);
+
 int magic_compile(magic_t, const char *);
 int magic_check(magic_t, const char *);
 int magic_list(magic_t, const char *);



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