From c1884ed7404c1d2d7e20f3b5f80bf9f809e8e458 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 9 Sep 2013 07:02:21 +0200 Subject: [PATCH] fix #1001689 - fix segfault when calling magic_load twice --- file-5.14-magic_load.patch | 178 +++++++++++++++++++++++++++++++++++++ file.spec | 7 +- 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 file-5.14-magic_load.patch diff --git a/file-5.14-magic_load.patch b/file-5.14-magic_load.patch new file mode 100644 index 0000000..f033f14 --- /dev/null +++ b/file-5.14-magic_load.patch @@ -0,0 +1,178 @@ +From 1198be74dcd8982dfcc9ba5a05e8950376ea74af Mon Sep 17 00:00:00 2001 +From: Christos Zoulas +Date: Thu, 2 May 2013 21:58:20 +0000 +Subject: [PATCH] PR/248: Multiple magic_loads fail due to global address + re-use. Add a struct to describe the set entries eliminating the global + variable. + +--- + src/apprentice.c | 58 +++++++++++++++++++++++++++++++------------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/src/apprentice.c b/src/apprentice.c +index 32ba2c0..aca977d 100644 +--- a/src/apprentice.c ++++ b/src/apprentice.c +@@ -80,6 +80,12 @@ struct magic_entry { + uint32_t max_count; + }; + ++struct magic_entry_set { ++ struct magic_entry *me; ++ uint32_t count; ++ uint32_t max; ++}; ++ + struct magic_map { + void *p; + size_t len; +@@ -125,7 +131,6 @@ private int apprentice_compile(struct magic_set *, struct magic_map *, + private int parse_apple(struct magic_set *, struct magic_entry *, const char *); + + +-private size_t maxmagic[MAGIC_SETS] = { 0 }; + private size_t magicsize = sizeof(struct magic); + + private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; +@@ -897,24 +902,24 @@ struct type_tbl_s { + + private int + addentry(struct magic_set *ms, struct magic_entry *me, +- struct magic_entry **mentry, uint32_t *mentrycount) ++ struct magic_entry_set *mset) + { + size_t i = me->mp->type == FILE_NAME ? 1 : 0; +- if (mentrycount[i] == maxmagic[i]) { ++ if (mset[i].count == mset[i].max) { + struct magic_entry *mp; + +- maxmagic[i] += ALLOC_INCR; ++ mset[i].max += ALLOC_INCR; + if ((mp = CAST(struct magic_entry *, +- realloc(mentry[i], sizeof(*mp) * maxmagic[i]))) == ++ realloc(mset[i].me, sizeof(*mp) * mset[i].max))) == + NULL) { +- file_oomem(ms, sizeof(*mp) * maxmagic[i]); ++ file_oomem(ms, sizeof(*mp) * mset[i].max); + return -1; + } +- (void)memset(&mp[mentrycount[i]], 0, sizeof(*mp) * ++ (void)memset(&mp[mset[i].count], 0, sizeof(*mp) * + ALLOC_INCR); +- mentry[i] = mp; ++ mset[i].me = mp; + } +- mentry[i][mentrycount[i]++] = *me; ++ mset[i].me[mset[i].count++] = *me; + memset(me, 0, sizeof(*me)); + return 0; + } +@@ -924,7 +929,7 @@ struct type_tbl_s { + */ + private void + load_1(struct magic_set *ms, int action, const char *fn, int *errs, +- struct magic_entry **mentry, uint32_t *mentrycount) ++ struct magic_entry_set *mset) + { + size_t lineno = 0, llen = 0; + char *line = NULL; +@@ -991,7 +996,7 @@ struct type_tbl_s { + case 0: + continue; + case 1: +- (void)addentry(ms, &me, mentry, mentrycount); ++ (void)addentry(ms, &me, mset); + goto again; + default: + (*errs)++; +@@ -1000,7 +1005,7 @@ struct type_tbl_s { + } + } + if (me.mp) +- (void)addentry(ms, &me, mentry, mentrycount); ++ (void)addentry(ms, &me, mset); + free(line); + (void)fclose(f); + } +@@ -1111,19 +1116,21 @@ struct type_tbl_s { + apprentice_load(struct magic_set *ms, const char *fn, int action) + { + int errs = 0; +- struct magic_entry *mentry[MAGIC_SETS] = { NULL }; +- uint32_t mentrycount[MAGIC_SETS] = { 0 }; + uint32_t i, j; + size_t files = 0, maxfiles = 0; + char **filearr = NULL, *mfn; + struct stat st; + struct magic_map *map; ++ struct magic_entry_set mset[MAGIC_SETS]; + DIR *dir; + struct dirent *d; + ++ memset(mset, 0, sizeof(mset)); + ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */ + +- if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { ++ ++ if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) ++ { + file_oomem(ms, sizeof(*map)); + return NULL; + } +@@ -1169,36 +1176,35 @@ struct type_tbl_s { + closedir(dir); + qsort(filearr, files, sizeof(*filearr), cmpstrp); + for (i = 0; i < files; i++) { +- load_1(ms, action, filearr[i], &errs, mentry, +- mentrycount); ++ load_1(ms, action, filearr[i], &errs, mset); + free(filearr[i]); + } + free(filearr); + } else +- load_1(ms, action, fn, &errs, mentry, mentrycount); ++ load_1(ms, action, fn, &errs, mset); + if (errs) + goto out; + + for (j = 0; j < MAGIC_SETS; j++) { + /* Set types of tests */ +- for (i = 0; i < mentrycount[j]; ) { +- if (mentry[j][i].mp->cont_level != 0) { ++ for (i = 0; i < mset[j].count; ) { ++ if (mset[j].me[i].mp->cont_level != 0) { + i++; + continue; + } +- i = set_text_binary(ms, mentry[j], mentrycount[j], i); ++ i = set_text_binary(ms, mset[j].me, mset[j].count, i); + } +- qsort(mentry[j], mentrycount[j], sizeof(*mentry[j]), ++ qsort(mset[j].me, mset[j].count, sizeof(*mset[j].me), + apprentice_sort); + + /* + * Make sure that any level 0 "default" line is last + * (if one exists). + */ +- set_last_default(ms, mentry[j], mentrycount[j]); ++ set_last_default(ms, mset[j].me, mset[j].count); + + /* coalesce per file arrays into a single one */ +- if (coalesce_entries(ms, mentry[j], mentrycount[j], ++ if (coalesce_entries(ms, mset[j].me, mset[j].count, + &map->magic[j], &map->nmagic[j]) == -1) { + errs++; + goto out; +@@ -1207,7 +1213,7 @@ struct type_tbl_s { + + out: + for (j = 0; j < MAGIC_SETS; j++) +- magic_entry_free(mentry[j], mentrycount[j]); ++ magic_entry_free(mset[j].me, mset[j].count); + + if (errs) { + for (j = 0; j < MAGIC_SETS; j++) { +-- +1.8.4 + diff --git a/file.spec b/file.spec index 76a6ec4..68a5974 100644 --- a/file.spec +++ b/file.spec @@ -4,7 +4,7 @@ Summary: A utility for determining file types Name: file Version: 5.14 -Release: 12%{?dist} +Release: 13%{?dist} License: BSD Group: Applications/File Source0: ftp://ftp.astron.com/pub/file/file-%{version}.tar.gz @@ -23,6 +23,7 @@ Patch9: file-5.14-elfspace.patch Patch10: file-5.14-bad-fsmagic-space.patch Patch11: file-5.14-no-magic.patch Patch12: file-5.14-journald.patch +Patch13: file-5.14-magic_load.patch URL: http://www.darwinsys.com/file/ Requires: file-libs = %{version}-%{release} BuildRequires: zlib-devel @@ -96,6 +97,7 @@ file(1) command. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 iconv -f iso-8859-1 -t utf-8 < doc/libmagic.man > doc/libmagic.man_ touch -r doc/libmagic.man doc/libmagic.man_ @@ -192,6 +194,9 @@ cd %{py3dir} %endif %changelog +* Mon Sep 09 2013 Jan Kaluza - 5.14-13 +- fix #1001689 - fix segfault when calling magic_load twice + * Thu Aug 22 2013 Jan Kaluza - 5.14-12 - fix #985072 - add support for journald files