From 0233e93b91666ed8a549818a1c859c5d6e6d0bbb Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2015 15:30:49 +0000 Subject: import file-5.11-31.el7 --- diff --git a/SOURCES/file-5.04-minix.patch b/SOURCES/file-5.04-minix.patch new file mode 100644 index 0000000..27f10db --- /dev/null +++ b/SOURCES/file-5.04-minix.patch @@ -0,0 +1,53 @@ +diff --git a/magic/Magdir/filesystems b/magic/Magdir/filesystems +index 9172dcb..25c24ca 100644 +--- a/magic/Magdir/filesystems ++++ b/magic/Magdir/filesystems +@@ -1351,32 +1351,40 @@ + # Minix filesystems - Juan Cespedes + 0x410 leshort 0x137f + !:strength / 2 +->0x402 beshort < 100 Minix filesystem, V1, %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V1, %d zones + >0x1e string minix \b, bootable + 0x410 beshort 0x137f + !:strength / 2 +->0x402 beshort < 100 Minix filesystem, V1 (big endian), %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V1 (big endian), %d zones + >0x1e string minix \b, bootable + 0x410 leshort 0x138f + !:strength / 2 +->0x402 beshort < 100 Minix filesystem, V1, 30 char names, %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V1, 30 char names, %d zones + >0x1e string minix \b, bootable + 0x410 beshort 0x138f + !:strength / 2 +->0x402 beshort < 100 Minix filesystem, V1, 30 char names (big endian), %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V1, 30 char names (big endian), %d zones + >0x1e string minix \b, bootable + 0x410 leshort 0x2468 +->0x402 beshort < 100 Minix filesystem, V2, %d zones ++>0x402 beshort < 100 ++>>0x402 beshort > -1 Minix filesystem, V2, %d zones + >0x1e string minix \b, bootable + 0x410 beshort 0x2468 +->0x402 beshort < 100 Minix filesystem, V2 (big endian), %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V2 (big endian), %d zones + >0x1e string minix \b, bootable + + 0x410 leshort 0x2478 +->0x402 beshort < 100 Minix filesystem, V2, 30 char names, %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V2, 30 char names, %d zones + >0x1e string minix \b, bootable + 0x410 leshort 0x2478 +->0x402 beshort < 100 Minix filesystem, V2, 30 char names, %d zones ++>0x402 beshort < 100 ++>0x402 beshort > -1 Minix filesystem, V2, 30 char names, %d zones + >0x1e string minix \b, bootable + 0x410 beshort 0x2478 + >0x402 beshort !0 Minix filesystem, V2, 30 char names (big endian), %d zones diff --git a/SOURCES/file-5.04-ppc32core.patch b/SOURCES/file-5.04-ppc32core.patch new file mode 100644 index 0000000..3aad1dd --- /dev/null +++ b/SOURCES/file-5.04-ppc32core.patch @@ -0,0 +1,12 @@ +diff --git a/src/readelf.c b/src/readelf.c +index 823db6e..9651239 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -218,6 +218,7 @@ static const size_t prpsoffsets32[] = { + 100, /* SunOS 5.x (command line) */ + 84, /* SunOS 5.x (short name) */ + ++ 48, /* PowerPC */ + 44, /* Linux (command line) */ + 28, /* Linux 2.0.36 (short name) */ + diff --git a/SOURCES/file-5.04-trim.patch b/SOURCES/file-5.04-trim.patch new file mode 100644 index 0000000..9aebda0 --- /dev/null +++ b/SOURCES/file-5.04-trim.patch @@ -0,0 +1,85 @@ +diff --git a/magic/Magdir/filesystems b/magic/Magdir/filesystems +index a2c2966..ecfa6c2 100644 +--- a/magic/Magdir/filesystems ++++ b/magic/Magdir/filesystems +@@ -1251,7 +1251,7 @@ + >>38917 byte >0x33 (unknown version, ID 0x%X) + >>38917 byte <0x31 (unknown version, ID 0x%X) + # "application id" which appears to be used as a volume label +->32808 string >\0 '%s' ++>32808 string/T >\0 '%s' + >34816 string \000CD001\001EL\ TORITO\ SPECIFICATION (bootable) + 37633 string CD001 ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors) + !:mime application/x-iso9660-image +diff --git a/src/apprentice.c b/src/apprentice.c +index 0490642..6dd8381 100644 +--- a/src/apprentice.c ++++ b/src/apprentice.c +@@ -1452,6 +1452,9 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp, + goto bad; + m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF; + break; ++ case CHAR_TRIM: ++ m->str_flags |= STRING_TRIM; ++ break; + default: + bad: + if (ms->flags & MAGIC_CHECK) +diff --git a/src/file.h b/src/file.h +index e02009f..1b5f53f 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -307,6 +307,7 @@ struct magic { + #define PSTRING_LEN \ + (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE) + #define PSTRING_LENGTH_INCLUDES_ITSELF BIT(12) ++#define STRING_TRIM BIT(13) + #define CHAR_COMPACT_WHITESPACE 'W' + #define CHAR_COMPACT_OPTIONAL_WHITESPACE 'w' + #define CHAR_IGNORE_LOWERCASE 'c' +@@ -321,6 +322,7 @@ struct magic { + #define CHAR_PSTRING_4_BE 'L' + #define CHAR_PSTRING_4_LE 'l' + #define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF 'J' ++#define CHAR_TRIM 'T' + #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE) + #define STRING_DEFAULT_RANGE 100 + +diff --git a/src/softmagic.c b/src/softmagic.c +index 8d08cad..f084edd 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -451,11 +451,30 @@ mprint(struct magic_set *ms, struct magic *m) + t = ms->offset + m->vallen; + } + else { ++ char *str = p->s; ++ ++ /* compute t before we mangle the string? */ ++ t = ms->offset + strlen(str); ++ + if (*m->value.s == '\0') +- p->s[strcspn(p->s, "\n")] = '\0'; +- if (file_printf(ms, m->desc, p->s) == -1) ++ str[strcspn(str, "\n")] = '\0'; ++ ++ if (m->str_flags & STRING_TRIM) { ++ char *last; ++ while (isspace((unsigned char)*str)) ++ str++; ++ last = str; ++ while (*last) ++ last++; ++ --last; ++ while (isspace((unsigned char)*last)) ++ last--; ++ *++last = '\0'; ++ } ++ ++ if (file_printf(ms, m->desc, str) == -1) + return -1; +- t = ms->offset + strlen(p->s); ++ + if (m->type == FILE_PSTRING) + t += file_pstring_length_size(m); + } diff --git a/SOURCES/file-5.11-CVE-2013-7345.patch b/SOURCES/file-5.11-CVE-2013-7345.patch index 0bb1287..cd04dc1 100644 --- a/SOURCES/file-5.11-CVE-2013-7345.patch +++ b/SOURCES/file-5.11-CVE-2013-7345.patch @@ -17,7 +17,7 @@ index 67c3eee..4a7d8dd 100644 0 string/wt #!\ /usr/bin/awk awk script text executable !:mime text/x-awk -0 regex =^\\s*BEGIN\\s*[{] awk script text -+0 regex =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text ++0 regex/4096 =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text +!:strength - 12 # AT&T Bell Labs' Plan 9 shell diff --git a/SOURCES/file-5.11-CVE-2014-0207.patch b/SOURCES/file-5.11-CVE-2014-0207.patch new file mode 100644 index 0000000..14f16bc --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-0207.patch @@ -0,0 +1,32 @@ +From 4fcb9a9d1b1063a65fbeb27395de4979c75bd962 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 3 Jun 2014 11:05:00 +0200 +Subject: [PATCH] Fix bug #67326 fileinfo: cdf_read_short_sector insufficient + boundary check + +Upstream fix https://github.com/file/file/commit/6d209c1c489457397a5763bca4b28e43aac90391.patch +Only revelant part applied +--- + ext/fileinfo/libmagic/cdf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index 4712e84..16649f1 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -367,10 +367,10 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, + size_t ss = CDF_SHORT_SEC_SIZE(h); + size_t pos = CDF_SHORT_SEC_POS(h, id); + assert(ss == len); +- if (pos > CDF_SEC_SIZE(h) * sst->sst_len) { ++ if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { + DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" + SIZE_T_FORMAT "u\n", +- pos, CDF_SEC_SIZE(h) * sst->sst_len)); ++ pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); + return -1; + } + (void)memcpy(((char *)buf) + offs, +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-0237.patch b/SOURCES/file-5.11-CVE-2014-0237.patch new file mode 100644 index 0000000..f533e2d --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-0237.patch @@ -0,0 +1,52 @@ +From 68ce2d0ea6da79b12a365e375e1c2ce882c77480 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 26 May 2014 17:50:14 -0700 +Subject: [PATCH] Fix bug #67328 (fileinfo: numerous file_printf calls + resulting in performance degradation) + +Upstream patch: https://github.com/file/file/commit/b8acc83781d5a24cc5101e525d15efe0482c280d +--- + ext/fileinfo/libmagic/cdf.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index dd7177e..8dacd2f 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -942,7 +942,7 @@ int + cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, + cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) + { +- size_t i, maxcount; ++ size_t maxcount; + const cdf_summary_info_header_t *si = + CAST(const cdf_summary_info_header_t *, sst->sst_tab); + const cdf_section_declaration_t *sd = +@@ -957,21 +957,13 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, + ssi->si_os = CDF_TOLE2(si->si_os); + ssi->si_class = si->si_class; + cdf_swap_class(&ssi->si_class); +- ssi->si_count = CDF_TOLE2(si->si_count); ++ ssi->si_count = CDF_TOLE4(si->si_count); + *count = 0; + maxcount = 0; + *info = NULL; +- for (i = 0; i < CDF_TOLE4(si->si_count); i++) { +- if (i >= CDF_LOOP_LIMIT) { +- DPRINTF(("Unpack summary info loop limit")); +- errno = EFTYPE; +- return -1; +- } +- if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), +- info, count, &maxcount) == -1) { ++ if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, ++ count, &maxcount) == -1) + return -1; +- } +- } + return 0; + } + +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-0238.patch b/SOURCES/file-5.11-CVE-2014-0238.patch new file mode 100644 index 0000000..07a0622 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-0238.patch @@ -0,0 +1,39 @@ +From 22736b7c56d678f142d5dd21f4996e5819507a2b Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Mon, 26 May 2014 17:42:18 -0700 +Subject: [PATCH] Fix bug #67327: fileinfo: CDF infinite loop in nelements DoS + +Upstream fix: https://github.com/file/file/commit/f97486ef5dc3e8735440edc4fc8808c63e1a3ef0 +--- + ext/fileinfo/libmagic/cdf.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index 8dacd2f..4712e84 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -823,6 +823,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, + i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); + if (inp[i].pi_type & CDF_VECTOR) { + nelements = CDF_GETUINT32(q, 1); ++ if (nelements == 0) { ++ DPRINTF(("CDF_VECTOR with nelements == 0\n")); ++ goto out; ++ } + o = 2; + } else { + nelements = 1; +@@ -897,7 +901,9 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, + } + DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", + nelements)); +- for (j = 0; j < nelements; j++, i++) { ++ for (j = 0; j < nelements && i < sh.sh_properties; ++ j++, i++) ++ { + uint32_t l = CDF_GETUINT32(q, o); + inp[i].pi_str.s_len = l; + inp[i].pi_str.s_buf = (const char *) +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-1943.patch b/SOURCES/file-5.11-CVE-2014-1943.patch index bcfa7e5..6b7c19c 100644 --- a/SOURCES/file-5.11-CVE-2014-1943.patch +++ b/SOURCES/file-5.11-CVE-2014-1943.patch @@ -96,7 +96,7 @@ index 22e1190..56f09ee 100644 } #endif - switch (mget(ms, s, m, nbytes, cont_level, text)) { -+ switch (mget(ms, s, m, nbytes, cont_level, text, recursion_level)) { ++ switch (mget(ms, s, m, nbytes, cont_level, text, recursion_level + 1)) { case -1: return -1; case 0: diff --git a/SOURCES/file-5.11-CVE-2014-3478.patch b/SOURCES/file-5.11-CVE-2014-3478.patch new file mode 100644 index 0000000..dc8b2f1 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3478.patch @@ -0,0 +1,41 @@ +From e77659a8c87272e5061738a31430d2111482c426 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 10 Jun 2014 14:02:36 +0200 +Subject: [PATCH] Fixed Bug #67410 fileinfo: mconvert incorrect handling of + truncated pascal string size + +Upstream +https://github.com/file/file/commit/27a14bc7ba285a0a5ebfdb55e54001aa11932b08 +--- + ext/fileinfo/libmagic/softmagic.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c +index 21fea6b..01e4977 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -881,10 +881,18 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) + return 1; + } + case FILE_PSTRING: { +- char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m); ++ size_t sz = file_pstring_length_size(m); ++ char *ptr1 = p->s, *ptr2 = ptr1 + sz; + size_t len = file_pstring_get_length(m, ptr1); +- if (len >= sizeof(p->s)) +- len = sizeof(p->s) - 1; ++ if (len >= sizeof(p->s)) { ++ /* ++ * The size of the pascal string length (sz) ++ * is 1, 2, or 4. We need at least 1 byte for NUL ++ * termination, but we've already truncated the ++ * string by p->s, so we need to deduct sz. ++ */ ++ len = sizeof(p->s) - sz; ++ } + while (len--) + *ptr1++ = *ptr2++; + *ptr1 = '\0'; +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-3479.patch b/SOURCES/file-5.11-CVE-2014-3479.patch new file mode 100644 index 0000000..1570695 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3479.patch @@ -0,0 +1,37 @@ +From 5c9f96799961818944d43b22c241cc56c215c2e4 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 10 Jun 2014 14:13:14 +0200 +Subject: [PATCH] Fixed Bug #67411 fileinfo: cdf_check_stream_offset + insufficient boundary check + +Upstream: +https://github.com/file/file/commit/36fadd29849b8087af9f4586f89dbf74ea45be67 +--- + ext/fileinfo/libmagic/cdf.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index 16649f1..c9a5d50 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -277,13 +277,15 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, + { + const char *b = (const char *)sst->sst_tab; + const char *e = ((const char *)p) + tail; ++ size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? ++ CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); + (void)&line; +- if (e >= b && (size_t)(e - b) < CDF_SEC_SIZE(h) * sst->sst_len) ++ if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) + return 0; + DPRINTF(("%d: offset begin %p end %p %" SIZE_T_FORMAT "u" + " >= %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %" + SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b), +- CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len)); ++ ss * sst->sst_len, ss, sst->sst_len)); + errno = EFTYPE; + return -1; + } +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-3480.patch b/SOURCES/file-5.11-CVE-2014-3480.patch new file mode 100644 index 0000000..042f0a9 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3480.patch @@ -0,0 +1,40 @@ +From 40ef6e07e0b2cdced57c506e08cf18f47122292d Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 10 Jun 2014 14:22:04 +0200 +Subject: [PATCH] Bug #67412 fileinfo: cdf_count_chain insufficient + boundary check + +Upstream: +https://github.com/file/file/commit/40bade80cbe2af1d0b2cd0420cebd5d5905a2382 +--- + ext/fileinfo/libmagic/cdf.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index c9a5d50..ee467a6 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -470,7 +470,8 @@ size_t + cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) + { + size_t i, j; +- cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size); ++ cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size) ++ / sizeof(maxsector)); + + DPRINTF(("Chain:")); + for (j = i = 0; sid >= 0; i++, j++) { +@@ -480,8 +481,8 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) + errno = EFTYPE; + return (size_t)-1; + } +- if (sid > maxsector) { +- DPRINTF(("Sector %d > %d\n", sid, maxsector)); ++ if (sid >= maxsector) { ++ DPRINTF(("Sector %d >= %d\n", sid, maxsector)); + errno = EFTYPE; + return (size_t)-1; + } +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-3487.patch b/SOURCES/file-5.11-CVE-2014-3487.patch new file mode 100644 index 0000000..2eddc2e --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3487.patch @@ -0,0 +1,34 @@ +From 25b1dc917a53787dbb2532721ca22f3f36eb13c0 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 10 Jun 2014 14:33:37 +0200 +Subject: [PATCH] Fixed Bug #67413 fileinfo: cdf_read_property_info + insufficient boundary chec + +Upstream: +https://github.com/file/file/commit/93e063ee374b6a75729df9e7201fb511e47e259d + +Adapted for C standard. +--- + ext/fileinfo/libmagic/cdf.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index ee467a6..429f3b9 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -812,7 +812,11 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, + if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1) + goto out; + for (i = 0; i < sh.sh_properties; i++) { +- size_t ofs = CDF_GETUINT32(p, (i << 1) + 1); ++ size_t ofs, tail = (i << 1) + 1; ++ if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t), ++ __LINE__) == -1) ++ goto out; ++ ofs = CDF_GETUINT32(p, tail); + q = (const uint8_t *)(const void *) + ((const char *)(const void *)p + ofs + - 2 * sizeof(uint32_t)); +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-3538.patch b/SOURCES/file-5.11-CVE-2014-3538.patch new file mode 100644 index 0000000..c70f851 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3538.patch @@ -0,0 +1,84 @@ +diff --git a/src/softmagic.c b/src/softmagic.c +index f848f94..ee979b9 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -50,7 +50,7 @@ private int32_t mprint(struct magic_set *, struct magic *); + private int32_t moffset(struct magic_set *, struct magic *); + private void mdebug(uint32_t, const char *, size_t); + private int mcopy(struct magic_set *, union VALUETYPE *, int, int, +- const unsigned char *, uint32_t, size_t, size_t); ++ const unsigned char *, uint32_t, size_t, struct magic *); + private int mconvert(struct magic_set *, struct magic *); + private int print_sep(struct magic_set *, int); + private int handle_annotation(struct magic_set *, struct magic *); +@@ -936,7 +936,7 @@ mdebug(uint32_t offset, const char *str, size_t len) + + private int + mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, +- const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt) ++ const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) + { + /* + * Note: FILE_SEARCH and FILE_REGEX do not actually copy +@@ -956,15 +956,24 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, + const char *last; /* end of search region */ + const char *buf; /* start of search region */ + const char *end; +- size_t lines; ++ size_t lines, linecnt, bytecnt; + ++ linecnt = m->str_range; ++ bytecnt = linecnt * 80; ++ ++ if (bytecnt == 0) { ++ bytecnt = 8192; ++ } ++ if (bytecnt > nbytes) { ++ bytecnt = nbytes; ++ } + if (s == NULL) { + ms->search.s_len = 0; + ms->search.s = NULL; + return 0; + } + buf = RCAST(const char *, s) + offset; +- end = last = RCAST(const char *, s) + nbytes; ++ end = last = RCAST(const char *, s) + bytecnt; + /* mget() guarantees buf <= last */ + for (lines = linecnt, b = buf; lines && b < end && + ((b = CAST(const char *, +@@ -977,7 +986,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, + b++; + } + if (lines) +- last = RCAST(const char *, s) + nbytes; ++ last = RCAST(const char *, s) + bytecnt; + + ms->search.s = buf; + ms->search.s_len = last - buf; +@@ -1050,7 +1059,6 @@ mget(struct magic_set *ms, const unsigned char *s, + int recursion_level) + { + uint32_t offset = ms->offset; +- uint32_t count = m->str_range; + union VALUETYPE *p = &ms->ms_value; + + if (recursion_level >= 20) { +@@ -1058,7 +1066,7 @@ mget(struct magic_set *ms, const unsigned char *s, + return -1; + } + +- if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) ++ if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, (uint32_t)nbytes, m) == -1) + return -1; + + if ((ms->flags & MAGIC_DEBUG) != 0) { +@@ -1546,7 +1554,7 @@ mget(struct magic_set *ms, const unsigned char *s, + if (m->flag & INDIROFFADD) { + offset += ms->c.li[cont_level-1].off; + } +- if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1) ++ if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1) + return -1; + ms->offset = offset; + diff --git a/SOURCES/file-5.11-CVE-2014-3587.patch b/SOURCES/file-5.11-CVE-2014-3587.patch new file mode 100644 index 0000000..5dcc3a7 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3587.patch @@ -0,0 +1,26 @@ +From 7ba1409a1aee5925180de546057ddd84ff267947 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Thu, 14 Aug 2014 17:19:03 -0700 +Subject: [PATCH] Fix bug #67716 - Segfault in cdf.c + +--- + NEWS | 1 + + ext/fileinfo/libmagic/cdf.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c +index 429f3b9..2c0a2d9 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -820,7 +820,7 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, + q = (const uint8_t *)(const void *) + ((const char *)(const void *)p + ofs + - 2 * sizeof(uint32_t)); +- if (q > e) { ++ if (q < p || q > e) { + DPRINTF(("Ran of the end %p > %p\n", q, e)); + goto out; + } +-- +1.9.2 + diff --git a/SOURCES/file-5.11-CVE-2014-3710.patch b/SOURCES/file-5.11-CVE-2014-3710.patch new file mode 100644 index 0000000..71303a3 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-3710.patch @@ -0,0 +1,35 @@ +From 1803228597e82218a8c105e67975bc50e6f5bf0d Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Wed, 22 Oct 2014 15:37:04 +0200 +Subject: [PATCH] Fix bug #68283: fileinfo: out-of-bounds read in elf note + headers + +Upstream commit +https://github.com/file/file/commit/39c7ac1106be844a5296d3eb5971946cc09ffda0 + +CVE -2014-3710 +--- + ext/fileinfo/libmagic/readelf.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/ext/fileinfo/libmagic/readelf.c b/ext/fileinfo/libmagic/readelf.c +index 1c3845f..bb6f70f 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -372,6 +372,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + uint32_t namesz, descsz; + unsigned char *nbuf = CAST(unsigned char *, vbuf); + ++ if (xnh_sizeof + offset > size) { ++ /* ++ * We're out of note headers. ++ */ ++ return xnh_sizeof + offset; ++ } ++ + (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); + offset += xnh_sizeof; + +-- +2.1.0 + diff --git a/SOURCES/file-5.11-CVE-2014-8116.patch b/SOURCES/file-5.11-CVE-2014-8116.patch new file mode 100644 index 0000000..2dc1f61 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-8116.patch @@ -0,0 +1,124 @@ +diff --git a/src/elfclass.h b/src/elfclass.h +index 010958a..0826ce3 100644 +--- a/src/elfclass.h ++++ b/src/elfclass.h +@@ -35,10 +35,12 @@ + switch (type) { + #ifdef ELFCORE + case ET_CORE: ++ phnum = elf_getu16(swap, elfhdr.e_phnum); ++ if (phnum > MAX_PHNUM) ++ return toomany(ms, "program", phnum); + flags |= FLAGS_IS_CORE; + if (dophn_core(ms, clazz, swap, fd, +- (off_t)elf_getu(swap, elfhdr.e_phoff), +- elf_getu16(swap, elfhdr.e_phnum), ++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, + (size_t)elf_getu16(swap, elfhdr.e_phentsize), + fsize, &flags) == -1) + return -1; +@@ -46,18 +48,24 @@ + #endif + case ET_EXEC: + case ET_DYN: ++ phnum = elf_getu16(swap, elfhdr.e_phnum); ++ if (phnum > MAX_PHNUM) ++ return toomany(ms, "program", phnum); ++ shnum = elf_getu16(swap, elfhdr.e_shnum); ++ if (shnum > MAX_SHNUM) ++ return toomany(ms, "section", shnum); + if (dophn_exec(ms, clazz, swap, fd, +- (off_t)elf_getu(swap, elfhdr.e_phoff), +- elf_getu16(swap, elfhdr.e_phnum), ++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, + (size_t)elf_getu16(swap, elfhdr.e_phentsize), +- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum)) +- == -1) ++ fsize, &flags, shnum) == -1) + return -1; + /*FALLTHROUGH*/ + case ET_REL: ++ shnum = elf_getu16(swap, elfhdr.e_shnum); ++ if (shnum > MAX_SHNUM) ++ return toomany(ms, "section", shnum); + if (doshn(ms, clazz, swap, fd, +- (off_t)elf_getu(swap, elfhdr.e_shoff), +- elf_getu16(swap, elfhdr.e_shnum), ++ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, + (size_t)elf_getu16(swap, elfhdr.e_shentsize), + fsize, &flags, elf_getu16(swap, elfhdr.e_machine), + (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1) +diff --git a/src/readelf.c b/src/readelf.c +index de016b5..1f4d1f4 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t); + private uint32_t getu32(int, uint32_t); + private uint64_t getu64(int, uint64_t); + ++#define MAX_PHNUM 2048 ++#define MAX_SHNUM 32768 ++ ++private int ++toomany(struct magic_set *ms, const char *name, uint16_t num) ++{ ++ if (file_printf(ms, ", too many %s header sections (%u)", name, num ++ ) == -1) ++ return -1; ++ return 0; ++} ++ + private uint16_t + getu16(int swap, uint16_t value) + { +@@ -388,13 +400,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + if (namesz & 0x80000000) { + (void)file_printf(ms, ", bad note name size 0x%lx", + (unsigned long)namesz); +- return offset; ++ return 0; + } + + if (descsz & 0x80000000) { + (void)file_printf(ms, ", bad note description size 0x%lx", + (unsigned long)descsz); +- return offset; ++ return 0; + } + + +@@ -851,6 +863,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + Elf32_Shdr sh32; + Elf64_Shdr sh64; + int stripped = 1; ++ size_t nbadcap = 0; + void *nbuf; + off_t noff, coff, name_off; + uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ +@@ -928,6 +941,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + free(nbuf); + break; + case SHT_SUNW_cap: ++ if (nbadcap > 5) ++ break; + if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { + file_badseek(ms); + return -1; +@@ -963,6 +978,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + (unsigned long long)xcap_tag, + (unsigned long long)xcap_val) == -1) + return -1; ++ if (nbadcap++ > 2) ++ coff = xsh_size; + break; + } + } +@@ -1142,7 +1159,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, + int flags = 0; + Elf32_Ehdr elf32hdr; + Elf64_Ehdr elf64hdr; +- uint16_t type; ++ uint16_t type, phnum, shnum; + + if (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) + return 0; diff --git a/SOURCES/file-5.11-CVE-2014-8117.patch b/SOURCES/file-5.11-CVE-2014-8117.patch new file mode 100644 index 0000000..f1ccb2f --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-8117.patch @@ -0,0 +1,129 @@ +diff --git a/src/file.h b/src/file.h +index 28f9bc7..f55d47f 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -446,6 +446,14 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *, + #endif /* __EMX__ */ + + ++typedef struct { ++ char *buf; ++ uint32_t offset; ++} file_pushbuf_t; ++ ++protected file_pushbuf_t *file_push_buffer(struct magic_set *); ++protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *); ++ + #ifndef COMPILE_ONLY + extern const char *file_names[]; + extern const size_t file_nnames; +diff --git a/src/funcs.c b/src/funcs.c +index 0d645eb..04bab02 100644 +--- a/src/funcs.c ++++ b/src/funcs.c +@@ -459,3 +459,43 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep) + return nm; + } + } ++ ++protected file_pushbuf_t * ++file_push_buffer(struct magic_set *ms) ++{ ++ file_pushbuf_t *pb; ++ ++ if (ms->event_flags & EVENT_HAD_ERR) ++ return NULL; ++ ++ if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL) ++ return NULL; ++ ++ pb->buf = ms->o.buf; ++ pb->offset = ms->offset; ++ ++ ms->o.buf = NULL; ++ ms->offset = 0; ++ ++ return pb; ++} ++ ++protected char * ++file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) ++{ ++ char *rbuf; ++ ++ if (ms->event_flags & EVENT_HAD_ERR) { ++ free(pb->buf); ++ free(pb); ++ return NULL; ++ } ++ ++ rbuf = ms->o.buf; ++ ++ ms->o.buf = pb->buf; ++ ms->offset = pb->offset; ++ ++ free(pb); ++ return rbuf; ++} +diff --git a/src/softmagic.c b/src/softmagic.c +index ee979b9..3695add 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -60,6 +60,7 @@ private void cvt_32(union VALUETYPE *, const struct magic *); + private void cvt_64(union VALUETYPE *, const struct magic *); + + #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) ++ + /* + * softmagic - lookup one file in parsed, in-memory copy of database + * Passed the name and FILE * of one file to be typed. +@@ -1060,6 +1061,9 @@ mget(struct magic_set *ms, const unsigned char *s, + { + uint32_t offset = ms->offset; + union VALUETYPE *p = &ms->ms_value; ++ file_pushbuf_t *pb; ++ char *rbuf; ++ int rv; + + if (recursion_level >= 20) { + file_error(ms, 0, "recursion nesting exceeded"); +@@ -1620,16 +1624,34 @@ mget(struct magic_set *ms, const unsigned char *s, + break; + + case FILE_INDIRECT: +- if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && +- file_printf(ms, "%s", m->desc) == -1) +- return -1; + if (offset == 0) + return 0; ++ + if (nbytes < offset) +- return 0; +- return file_softmagic(ms, s + offset, nbytes - offset, ++ return 0; ++ ++ if ((pb = file_push_buffer(ms)) == NULL) ++ return -1; ++ ++ rv = file_softmagic(ms, s + offset, nbytes - offset, + recursion_level, BINTEST, text); + ++ if ((ms->flags & MAGIC_DEBUG) != 0) ++ fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); ++ ++ rbuf = file_pop_buffer(ms, pb); ++ if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR) ++ return -1; ++ ++ if (rv == 1) { ++ if (file_printf(ms, "%s", rbuf) == -1) { ++ free(rbuf); ++ return -1; ++ } ++ } ++ free(rbuf); ++ return rv; ++ + case FILE_DEFAULT: /* nothing to check */ + default: + break; diff --git a/SOURCES/file-5.11-CVE-2014-9652.patch b/SOURCES/file-5.11-CVE-2014-9652.patch new file mode 100644 index 0000000..2384d90 --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-9652.patch @@ -0,0 +1,34 @@ +From 59e63838913eee47f5c120a6c53d4565af638158 Mon Sep 17 00:00:00 2001 +From: Christos Zoulas +Date: Tue, 11 Nov 2014 17:48:23 +0000 +Subject: [PATCH] PR/398: Correctly truncate pascal strings (fixes out of + bounds read of 1, 2, or 4 bytes). + +--- + src/softmagic.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/softmagic.c b/src/softmagic.c +index dbb670a..2b15f2c 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -964,14 +964,17 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) + size_t sz = file_pstring_length_size(m); + char *ptr1 = p->s, *ptr2 = ptr1 + sz; + size_t len = file_pstring_get_length(m, ptr1); +- if (len >= sizeof(p->s)) { ++ sz = sizeof(p->s) - sz; /* maximum length of string */ ++ if (len >= sz) { + /* + * The size of the pascal string length (sz) + * is 1, 2, or 4. We need at least 1 byte for NUL + * termination, but we've already truncated the + * string by p->s, so we need to deduct sz. ++ * Because we can use one of the bytes of the length ++ * after we shifted as NUL termination. + */ +- len = sizeof(p->s) - sz; ++ len = sz; + } + while (len--) + *ptr1++ = *ptr2++; diff --git a/SOURCES/file-5.11-CVE-2014-9653.patch b/SOURCES/file-5.11-CVE-2014-9653.patch new file mode 100644 index 0000000..b1765dc --- /dev/null +++ b/SOURCES/file-5.11-CVE-2014-9653.patch @@ -0,0 +1,67 @@ +diff --git a/src/readelf.c b/src/readelf.c +index 1f4d1f4..05ec736 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -327,7 +327,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + * Loop through all the program headers. + */ + for ( ; num; num--) { +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) { ++ if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { + file_badread(ms); + return -1; + } +@@ -869,6 +869,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ + uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ + char name[50]; ++ ssize_t namesize; + + if (size != xsh_sizeof) { + if (file_printf(ms, ", corrupted section header size") == -1) +@@ -877,7 +878,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + } + + /* Read offset of name section to be able to read section names later */ +- if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) { ++ if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) < (ssize_t)xsh_sizeof) { + file_badread(ms); + return -1; + } +@@ -885,15 +886,15 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + + for ( ; num; num--) { + /* Read the name of this section. */ +- if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) { ++ if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) { + file_badread(ms); + return -1; + } +- name[sizeof(name) - 1] = '\0'; ++ name[namesize] = '\0'; + if (strcmp(name, ".debug_info") == 0) + stripped = 0; + +- if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) { ++ if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) { + file_badread(ms); + return -1; + } +@@ -923,7 +924,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + " for note"); + return -1; + } +- if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) { ++ if (pread(fd, nbuf, xsh_size, xsh_offset) < (ssize_t)xsh_size) { + file_badread(ms); + free(nbuf); + return -1; +@@ -1076,7 +1077,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + } + + for ( ; num; num--) { +- if (pread(fd, xph_addr, xph_sizeof, off) == -1) { ++ if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) { + file_badread(ms); + return -1; + } diff --git a/SOURCES/file-5.11-add-aarch64.patch b/SOURCES/file-5.11-add-aarch64.patch new file mode 100644 index 0000000..89cc430 --- /dev/null +++ b/SOURCES/file-5.11-add-aarch64.patch @@ -0,0 +1,32 @@ +From a5c989d3d36e51293a0474c4653f595dcfb94751 Mon Sep 17 00:00:00 2001 +From: Jeffrey Bastian +Date: Thu, 20 Feb 2014 15:45:42 -0500 +Subject: [PATCH] add aarch64 + +backport of upstream https://github.com/glensc/file/commit/2dccf6a6615f +--- + magic/Magdir/elf | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/magic/Magdir/elf b/magic/Magdir/elf +index 8e3b7bc..e0e9937 100644 +--- a/magic/Magdir/elf ++++ b/magic/Magdir/elf +@@ -148,12 +148,11 @@ + >>18 leshort 97 NatSemi 32k, + >>18 leshort 106 Analog Devices Blackfin, + >>18 leshort 113 Altera Nios II, +->>18 leshort 0xae META, ++>>18 leshort 174 META, ++>>18 leshort 183 ARM aarch64, + >>18 leshort 187 Tilera TILE64, + >>18 leshort 188 Tilera TILEPro, + >>18 leshort 191 Tilera TILE-Gx, +->>18 leshort 0x3426 OpenRISC (obsolete), +->>18 leshort 0x8472 OpenRISC (obsolete), + >>18 leshort 0x9026 Alpha (unofficial), + >>20 lelong 0 invalid version + >>20 lelong 1 version 1 +-- +1.8.3.1 + diff --git a/SOURCES/file-5.11-buildid.patch b/SOURCES/file-5.11-buildid.patch new file mode 100644 index 0000000..f06487c --- /dev/null +++ b/SOURCES/file-5.11-buildid.patch @@ -0,0 +1,32 @@ +From 26f146f7dcf96f8f0a5b2f0503bdb4c46b74cf56 Mon Sep 17 00:00:00 2001 +From: Christos Zoulas +Date: Wed, 31 Oct 2012 17:03:41 +0000 +Subject: [PATCH] PR/208: Fix buildid format + +--- + src/readelf.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/readelf.c b/src/readelf.c +index deb6d31..158f789 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -465,13 +465,14 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size, + + if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && + xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) { +- uint32_t desc[5], i; +- if (file_printf(ms, ", BuildID[%s]=0x", descsz == 16 ? "md5/uuid" : ++ uint8_t desc[20]; ++ uint32_t i; ++ if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" : + "sha1") == -1) + return size; + (void)memcpy(desc, &nbuf[doff], descsz); +- for (i = 0; i < descsz >> 2; i++) +- if (file_printf(ms, "%.8x", desc[i]) == -1) ++ for (i = 0; i < descsz; i++) ++ if (file_printf(ms, "%02x", desc[i]) == -1) + return size; + *flags |= FLAGS_DID_BUILD_ID; + } diff --git a/SOURCES/file-5.11-maxmime.patch b/SOURCES/file-5.11-maxmime.patch deleted file mode 100644 index 7cc5ee2..0000000 --- a/SOURCES/file-5.11-maxmime.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit 774f9f6653a90d83a8b5802e7dd210a45603e039 -Author: Christos Zoulas -Date: Fri Jan 25 23:07:19 2013 +0000 - - bump mime desc - -diff --git a/src/file.h b/src/file.h -index 8e139fc..4c03766 100644 -@@ -128,12 +128,13 @@ - #endif - #define MAXMAGIS 8192 /* max entries in any one magic file - or directory */ --#define MAXDESC 64 /* max leng of text description/MIME type */ --#define MAXstring 64 /* max leng of "string" types */ -+#define MAXDESC 64 /* max len of text description/MIME type */ -+#define MAXMIME 80 /* max len of text MIME type */ -+#define MAXstring 64 /* max len of "string" types */ - - #define MAGICNO 0xF11E041C --#define VERSIONNO 9 --#define FILE_MAGICSIZE 232 -+#define VERSIONNO 10 -+#define FILE_MAGICSIZE 248 - - #define FILE_LOAD 0 - #define FILE_CHECK 1 -@@ -300,9 +301,9 @@ struct magic { - union VALUETYPE value; /* either number or string */ - /* Words 17-32 */ - char desc[MAXDESC]; /* description */ -- /* Words 33-48 */ -- char mimetype[MAXDESC]; /* MIME type */ -- /* Words 49-50 */ -+ /* Words 33-52 */ -+ char mimetype[MAXMIME]; /* MIME type */ -+ /* Words 53-54 */ - char apple[8]; - }; - diff --git a/SOURCES/file-5.11-offset-oob.patch b/SOURCES/file-5.11-offset-oob.patch new file mode 100644 index 0000000..a143f44 --- /dev/null +++ b/SOURCES/file-5.11-offset-oob.patch @@ -0,0 +1,31 @@ +diff --git a/src/softmagic.c b/src/softmagic.c +index 8d08cad..6dc86f5 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -41,8 +41,6 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $") + #include + #include + +-#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) >= ((n) - (o))) +- + private int match(struct magic_set *, struct magic *, uint32_t, + const unsigned char *, size_t, int, int, int); + private int mget(struct magic_set *, const unsigned char *, +@@ -1582,7 +1580,7 @@ mget(struct magic_set *ms, const unsigned char *s, + break; + + case FILE_REGEX: +- if (OFFSET_OOB(nbytes, offset, 0)) ++ if (nbytes < offset) + return 0; + break; + +@@ -1592,7 +1590,7 @@ mget(struct magic_set *ms, const unsigned char *s, + return -1; + if (offset == 0) + return 0; +- if (OFFSET_OOB(nbytes, offset, 0)) ++ if (nbytes < offset) + return 0; + return file_softmagic(ms, s + offset, nbytes - offset, + recursion_level, BINTEST, text); diff --git a/SOURCES/file-5.11-ppc64.patch b/SOURCES/file-5.11-ppc64.patch new file mode 100644 index 0000000..44202ae --- /dev/null +++ b/SOURCES/file-5.11-ppc64.patch @@ -0,0 +1,29 @@ +diff --git a/magic/Magdir/elf b/magic/Magdir/elf +index e0e9937..11c876e 100644 +--- a/magic/Magdir/elf ++++ b/magic/Magdir/elf +@@ -84,10 +84,21 @@ + >>>48 leshort &0x0008 (LP64), + >>18 leshort 16 nCUBE, + >>18 leshort 17 Fujitsu VPP500, +->>18 leshort 18 SPARC32PLUS - invalid byte order, +->>18 leshort 20 PowerPC, ++>>18 leshort 18 SPARC32PLUS, ++# only for 32-bit ++>>>4 byte 1 ++>>>>36 lelong&0xffff00 0x000100 V8+ Required, ++>>>>36 lelong&0xffff00 0x000200 Sun UltraSPARC1 Extensions Required, ++>>>>36 lelong&0xffff00 0x000400 HaL R1 Extensions Required, ++>>>>36 lelong&0xffff00 0x000800 Sun UltraSPARC3 Extensions Required, ++>>18 leshort 19 Intel 80960, ++>>18 leshort 20 PowerPC or cisco 4500, ++>>18 leshort 21 64-bit PowerPC or cisco 7500, + >>18 leshort 22 IBM S/390, +->>18 leshort 36 NEC V800, ++>>18 leshort 23 Cell SPU, ++>>18 leshort 24 cisco SVIP, ++>>18 leshort 25 cisco 7200, ++>>18 leshort 36 NEC V800 or cisco 12000, + >>18 leshort 37 Fujitsu FR20, + >>18 leshort 38 TRW RH-32, + >>18 leshort 39 Motorola RCE, diff --git a/SOURCES/file-5.11-softmagic-read.patch b/SOURCES/file-5.11-softmagic-read.patch new file mode 100644 index 0000000..154b8d0 --- /dev/null +++ b/SOURCES/file-5.11-softmagic-read.patch @@ -0,0 +1,17 @@ +diff --git a/src/softmagic.c b/src/softmagic.c +index 8d08cad..8262788 100644 +--- a/src/softmagic.c ++++ b/src/softmagic.c +@@ -199,9 +199,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, + if (file_check_mem(ms, ++cont_level) == -1) + return -1; + +- while (magic[magindex+1].cont_level != 0 && +- ++magindex < nmagic) { +- m = &magic[magindex]; ++ while (magindex + 1 < nmagic && ++ magic[magindex + 1].cont_level != 0) { ++ m = &magic[++magindex]; + ms->line = m->lineno; /* for messages */ + + if (cont_level < m->cont_level) diff --git a/SOURCES/file-5.11-stripped.patch b/SOURCES/file-5.11-stripped.patch new file mode 100644 index 0000000..b0cef3b --- /dev/null +++ b/SOURCES/file-5.11-stripped.patch @@ -0,0 +1,318 @@ +diff --git a/configure.ac b/configure.ac +index 1511c9a..97a4689 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -159,7 +159,7 @@ dnl Checks for functions + AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof fork) + + dnl Provide implementation of some required functions if necessary +-AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline) ++AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline pread) + + dnl Checks for libraries + AC_CHECK_LIB(z,gzopen) +diff --git a/src/cdf.c b/src/cdf.c +index d05d279..3b2b79b 100644 +--- a/src/cdf.c ++++ b/src/cdf.c +@@ -35,7 +35,7 @@ + #include "file.h" + + #ifndef lint +-FILE_RCSID("@(#)$File: cdf.c,v 1.50 2012/02/20 22:35:29 christos Exp $") ++FILE_RCSID("@(#)$File: cdf.c,v 1.51 2012/03/20 18:28:02 christos Exp $") + #endif + + #include +@@ -296,10 +296,7 @@ cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len) + if (info->i_fd == -1) + return -1; + +- if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1) +- return -1; +- +- if (read(info->i_fd, buf, len) != (ssize_t)len) ++ if (pread(info->i_fd, buf, len, off) != (ssize_t)len) + return -1; + + return (ssize_t)len; +diff --git a/src/elfclass.h b/src/elfclass.h +index 2e7741b..010958a 100644 +--- a/src/elfclass.h ++++ b/src/elfclass.h +@@ -59,7 +59,8 @@ + (off_t)elf_getu(swap, elfhdr.e_shoff), + elf_getu16(swap, elfhdr.e_shnum), + (size_t)elf_getu16(swap, elfhdr.e_shentsize), +- fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1) ++ fsize, &flags, elf_getu16(swap, elfhdr.e_machine), ++ (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1) + return -1; + break; + +diff --git a/src/file.h b/src/file.h +index 1b5f53f..28f9bc7 100644 +--- a/src/file.h ++++ b/src/file.h +@@ -462,6 +462,9 @@ extern char *sys_errlist[]; + #define strtoul(a, b, c) strtol(a, b, c) + #endif + ++#ifndef HAVE_PREAD ++ssize_t pread(int, void *, size_t, off_t); ++#endif + #ifndef HAVE_VASPRINTF + int vasprintf(char **, const char *, va_list); + #endif +diff --git a/src/readelf.c b/src/readelf.c +index ce4832a..8d355c5 100644 +--- a/src/readelf.c ++++ b/src/readelf.c +@@ -48,7 +48,7 @@ private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t, + private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, + off_t, int *, int); + private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, +- off_t, int *, int); ++ off_t, int *, int, int); + private size_t donote(struct magic_set *, void *, size_t, size_t, int, + int, size_t, int *); + +@@ -129,19 +129,21 @@ getu64(int swap, uint64_t value) + #define elf_getu32(swap, value) getu32(swap, value) + #ifdef USE_ARRAY_FOR_64BIT_TYPES + # define elf_getu64(swap, array) \ +- ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \ +- (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32))) ++ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 \ ++ : elf_getu32(swap, array[0])) + \ ++ (swap ? elf_getu32(swap, array[1]) : \ ++ ((uint64_t)elf_getu32(swap, array[1]) << 32))) + #else + # define elf_getu64(swap, value) getu64(swap, value) + #endif + + #define xsh_addr (clazz == ELFCLASS32 \ +- ? (void *) &sh32 \ +- : (void *) &sh64) ++ ? (void *)&sh32 \ ++ : (void *)&sh64) + #define xsh_sizeof (clazz == ELFCLASS32 \ +- ? sizeof sh32 \ +- : sizeof sh64) +-#define xsh_size (clazz == ELFCLASS32 \ ++ ? sizeof(sh32) \ ++ : sizeof(sh64)) ++#define xsh_size (size_t)(clazz == ELFCLASS32 \ + ? elf_getu32(swap, sh32.sh_size) \ + : elf_getu64(swap, sh64.sh_size)) + #define xsh_offset (off_t)(clazz == ELFCLASS32 \ +@@ -150,12 +152,15 @@ getu64(int swap, uint64_t value) + #define xsh_type (clazz == ELFCLASS32 \ + ? elf_getu32(swap, sh32.sh_type) \ + : elf_getu32(swap, sh64.sh_type)) ++#define xsh_name (clazz == ELFCLASS32 \ ++ ? elf_getu32(swap, sh32.sh_name) \ ++ : elf_getu32(swap, sh64.sh_name)) + #define xph_addr (clazz == ELFCLASS32 \ + ? (void *) &ph32 \ + : (void *) &ph64) + #define xph_sizeof (clazz == ELFCLASS32 \ +- ? sizeof ph32 \ +- : sizeof ph64) ++ ? sizeof(ph32) \ ++ : sizeof(ph64)) + #define xph_type (clazz == ELFCLASS32 \ + ? elf_getu32(swap, ph32.p_type) \ + : elf_getu32(swap, ph64.p_type)) +@@ -171,8 +176,8 @@ getu64(int swap, uint64_t value) + ? elf_getu32(swap, ph32.p_filesz) \ + : elf_getu64(swap, ph64.p_filesz))) + #define xnh_addr (clazz == ELFCLASS32 \ +- ? (void *) &nh32 \ +- : (void *) &nh64) ++ ? (void *)&nh32 \ ++ : (void *)&nh64) + #define xph_memsz (size_t)((clazz == ELFCLASS32 \ + ? elf_getu32(swap, ph32.p_memsz) \ + : elf_getu64(swap, ph64.p_memsz))) +@@ -192,8 +197,8 @@ getu64(int swap, uint64_t value) + ? prpsoffsets32[i] \ + : prpsoffsets64[i]) + #define xcap_addr (clazz == ELFCLASS32 \ +- ? (void *) &cap32 \ +- : (void *) &cap64) ++ ? (void *)&cap32 \ ++ : (void *)&cap64) + #define xcap_sizeof (clazz == ELFCLASS32 \ + ? sizeof cap32 \ + : sizeof cap64) +@@ -296,7 +301,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + { + Elf32_Phdr ph32; + Elf64_Phdr ph64; +- size_t offset; ++ size_t offset, len; + unsigned char nbuf[BUFSIZ]; + ssize_t bufsize; + +@@ -310,11 +315,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + * Loop through all the program headers. + */ + for ( ; num; num--) { +- if (lseek(fd, off, SEEK_SET) == (off_t)-1) { +- file_badseek(ms); +- return -1; +- } +- if (read(fd, xph_addr, xph_sizeof) == -1) { ++ if (pread(fd, xph_addr, xph_sizeof, off) == -1) { + file_badread(ms); + return -1; + } +@@ -332,13 +333,8 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + * This is a PT_NOTE section; loop through all the notes + * in the section. + */ +- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) { +- file_badseek(ms); +- return -1; +- } +- bufsize = read(fd, nbuf, +- ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf))); +- if (bufsize == -1) { ++ len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf); ++ if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) { + file_badread(ms); + return -1; + } +@@ -843,15 +839,16 @@ static const cap_desc_t cap_desc_386[] = { + + private int + doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, +- size_t size, off_t fsize, int *flags, int mach) ++ size_t size, off_t fsize, int *flags, int mach, int strtab) + { + Elf32_Shdr sh32; + Elf64_Shdr sh64; + int stripped = 1; + void *nbuf; +- off_t noff, coff; ++ off_t noff, coff, name_off; + uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */ + uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ ++ char name[50]; + + if (size != xsh_sizeof) { + if (file_printf(ms, ", corrupted section header size") == -1) +@@ -859,12 +856,24 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + return 0; + } + ++ /* Read offset of name section to be able to read section names later */ ++ if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) { ++ file_badread(ms); ++ return -1; ++ } ++ name_off = xsh_offset; ++ + for ( ; num; num--) { +- if (lseek(fd, off, SEEK_SET) == (off_t)-1) { +- file_badseek(ms); ++ /* Read the name of this section. */ ++ if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) { ++ file_badread(ms); + return -1; + } +- if (read(fd, xsh_addr, xsh_sizeof) == -1) { ++ name[sizeof(name) - 1] = '\0'; ++ if (strcmp(name, ".debug_info") == 0) ++ stripped = 0; ++ ++ if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) { + file_badread(ms); + return -1; + } +@@ -889,39 +898,30 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, + /* Things we can determine when we seek */ + switch (xsh_type) { + case SHT_NOTE: +- if ((nbuf = malloc((size_t)xsh_size)) == NULL) { ++ if ((nbuf = malloc(xsh_size)) == NULL) { + file_error(ms, errno, "Cannot allocate memory" + " for note"); + return -1; + } +- if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) == +- (off_t)-1) { ++ if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) { + file_badread(ms); + free(nbuf); + return -1; + } +- if (read(fd, nbuf, (size_t)xsh_size) != +- (ssize_t)xsh_size) { +- free(nbuf); +- file_badread(ms); +- return -1; +- } + + noff = 0; + for (;;) { + if (noff >= (off_t)xsh_size) + break; + noff = donote(ms, nbuf, (size_t)noff, +- (size_t)xsh_size, clazz, swap, 4, +- flags); ++ xsh_size, clazz, swap, 4, flags); + if (noff == 0) + break; + } + free(nbuf); + break; + case SHT_SUNW_cap: +- if (lseek(fd, (off_t)xsh_offset, SEEK_SET) == +- (off_t)-1) { ++ if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) { + file_badseek(ms); + return -1; + } +@@ -1043,7 +1043,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + const char *shared_libraries = ""; + unsigned char nbuf[BUFSIZ]; + ssize_t bufsize; +- size_t offset, align; ++ size_t offset, align, len; + + if (size != xph_sizeof) { + if (file_printf(ms, ", corrupted program header size") == -1) +@@ -1052,13 +1052,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + } + + for ( ; num; num--) { +- if (lseek(fd, off, SEEK_SET) == (off_t)-1) { +- file_badseek(ms); +- return -1; +- } +- +- if (read(fd, xph_addr, xph_sizeof) == -1) { +- file_badread(ms); ++ if (pread(fd, xph_addr, xph_sizeof, off) == -1) { ++ file_badread(ms); + return -1; + } + +@@ -1096,12 +1091,9 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off, + * This is a PT_NOTE section; loop through all the notes + * in the section. + */ +- if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) { +- file_badseek(ms); +- return -1; +- } +- bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ? +- xph_filesz : sizeof(nbuf))); ++ len = xph_filesz < sizeof(nbuf) ? xph_filesz ++ : sizeof(nbuf); ++ bufsize = pread(fd, nbuf, len, xph_offset); + if (bufsize == -1) { + file_badread(ms); + return -1; diff --git a/SOURCES/file-5.11-swap-info.patch b/SOURCES/file-5.11-swap-info.patch new file mode 100644 index 0000000..ec4e170 --- /dev/null +++ b/SOURCES/file-5.11-swap-info.patch @@ -0,0 +1,23 @@ +diff --git a/magic/Magdir/linux b/magic/Magdir/linux +index aa8d1aa..90f0f46 100644 +--- a/magic/Magdir/linux ++++ b/magic/Magdir/linux +@@ -87,7 +87,17 @@ + >0x41a beshort x \b%04x + # From Daniel Novotny + # swap file for PowerPC +-65526 string SWAPSPACE2 Linux/ppc swap file ++65526 string SWAPSPACE2 Linux swap file ++>0x400 long x version %d, ++>0x404 long x size %d pages, ++>1052 string \0 no label, ++>1052 string >\0 LABEL=%s, ++>0x40c belong x UUID=%08x ++>0x410 beshort x \b-%04x ++>0x412 beshort x \b-%04x ++>0x414 beshort x \b-%04x ++>0x416 belong x \b-%08x ++>0x41a beshort x \b%04x + 16374 string SWAPSPACE2 Linux/ia64 swap file + # + # Linux kernel boot images, from Albert Cahalan diff --git a/SOURCES/file-5.11-xml.patch b/SOURCES/file-5.11-xml.patch new file mode 100644 index 0000000..373fed5 --- /dev/null +++ b/SOURCES/file-5.11-xml.patch @@ -0,0 +1,47 @@ +diff --git a/magic/Magdir/sgml b/magic/Magdir/sgml +index 3f78c2f..991f90d 100644 +--- a/magic/Magdir/sgml ++++ b/magic/Magdir/sgml +@@ -17,16 +17,16 @@ + + # xhtml + 0 string/t \15 string >\0 +->>19 search/4096/cWbt \19 search/4096/cWbt \>15 string >\0 (version %.3s) + !:mime text/html + 0 string/t \15 string >\0 +->>19 search/4096/cWbt \19 search/4096/cWbt \>15 string >\0 (version %.3s) + !:mime text/html + 0 string/t \15 string >\0 +->>19 search/4096/cWbt \19 search/4096/cWbt \>15 string >\0 (version %.3s) + !:mime text/html + + #------------------------------------------------------------------------------ +@@ -59,17 +59,14 @@ + !:mime application/xml + 0 string/t \15 search/1 >\0 %.3s document text ++>15 string/t >\0 %.3s document text + >>23 search/1 \>24 search/1 \ doc/libmagic.man_ touch -r doc/libmagic.man doc/libmagic.man_ @@ -185,6 +237,56 @@ cd python %endif %changelog +* Mon Sep 07 2015 Jan Kaluza - 5.11-31 +- fix #1255396 - Make the build ID output consistent with other tools + +* Fri Aug 28 2015 Jan Kaluza - 5.11-30 +- fix CVE-2014-8116 - bump the acceptable ELF program headers count to 2048 + +* Mon Jul 13 2015 Jan Kaluza - 5.11-29 +- fix #839229 - fix detection of version of XML files + +* Mon Jul 13 2015 Jan Kaluza - 5.11-28 +- fix #839229 - fix detection of version of XML files + +* Tue Jul 07 2015 Jan Kaluza - 5.11-27 +- fix CVE-2014-0207 - cdf_read_short_sector insufficient boundary check +- fix CVE-2014-0237 - cdf_unpack_summary_info() excessive looping DoS +- fix CVE-2014-0238 - CDF property info parsing nelements infinite loop +- fix CVE-2014-3478 - mconvert incorrect handling of truncated pascal string +- fix CVE-2014-3479 - fix extensive backtracking in regular expression +- fix CVE-2014-3480 - cdf_count_chain insufficient boundary check +- fix CVE-2014-3487 - cdf_read_property_info insufficient boundary check +- fix CVE-2014-3538 - unrestricted regular expression matching +- fix CVE-2014-3587 - fix cdf_read_property_info +- fix CVE-2014-3710 - out-of-bounds read in elf note headers +- fix CVE-2014-8116 - multiple denial of service issues (resource consumption) +- fix CVE-2014-8117 - denial of service issue (resource consumption) +- fix CVE-2014-9652 - out of bounds read in mconvert() +- fix CVE-2014-9653 - malformed elf file causes access to uninitialized memory + +* Tue Jun 09 2015 Jan Kaluza - 5.11-26 +- fix #1080452 - remove .orig files from magic directory + +* Tue Jun 02 2015 Jan Kaluza - 5.11-25 +- fix #1224667, #1224668 - show additional info for Linux swap files + +* Mon May 11 2015 Jan Kaluza - 5.11-24 +- fix #1064268 - fix stray return -1 + +* Wed Apr 22 2015 Jan Kaluza - 5.11-23 +- fix #1094648 - improve Minix detection pattern to fix false positives +- fix #1161912 - trim white-spaces during ISO9660 detection +- fix #1157850 - fix detection of ppc64le ELF binaries +- fix #1161911 - display "from" field on 32bit ppc core +- fix #1064167 - revert MAXMIME patch +- fix #1064268 - detect Dwarf debuginfo as "not stripped" +- fix #1082689 - fix invalid read when matched pattern is the last one tried +- fix #1080362 - remove deadcode and OFFSET_OOB redefinition + +* Tue Jul 15 2014 Jan Kaluza - 5.11-22 +- fix #1067688 - add support for aarch64 ELF binaries + * Tue Mar 25 2014 Jan Kaluza - 5.11-21 - fix #1079848 - fix potential regression in Perl detection caused by previous fix