From owner-p4-projects@FreeBSD.ORG Thu Nov 29 17:05:18 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E4AED992; Thu, 29 Nov 2012 17:05:17 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9B95A990 for ; Thu, 29 Nov 2012 17:05:17 +0000 (UTC) (envelope-from brooks@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 7FFC48FC08 for ; Thu, 29 Nov 2012 17:05:17 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.5/8.14.5) with ESMTP id qATH5HJo038203 for ; Thu, 29 Nov 2012 17:05:17 GMT (envelope-from brooks@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.5/8.14.5/Submit) id qATH5Htj038200 for perforce@freebsd.org; Thu, 29 Nov 2012 17:05:17 GMT (envelope-from brooks@freebsd.org) Date: Thu, 29 Nov 2012 17:05:17 GMT Message-Id: <201211291705.qATH5Htj038200@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to brooks@freebsd.org using -f From: Brooks Davis Subject: PERFORCE change 219862 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.14 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Nov 2012 17:05:18 -0000 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 *);