From 2cffb73ae825f51c4cbe312e34b8b616b9637767 Mon Sep 17 00:00:00 2001 From: dogsheng <960055655@qq.com> Date: Wed, 25 Dec 2019 15:53:54 +0800 Subject: [PATCH] Package init --- CVE-2018-18585.patch | 37 +++++++++ CVE-2018-18586.patch | 174 +++++++++++++++++++++++++++++++++++++++++++ libmspack.spec | 7 +- 3 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 CVE-2018-18585.patch create mode 100644 CVE-2018-18586.patch diff --git a/CVE-2018-18585.patch b/CVE-2018-18585.patch new file mode 100644 index 0000000..ea82cb3 --- /dev/null +++ b/CVE-2018-18585.patch @@ -0,0 +1,37 @@ +From e9c3024874007015ff7ebd66ecff086698b9db91 Mon Sep 17 00:00:00 2001 +From: Stuart Caie +Date: Wed, 17 Oct 2018 11:29:03 +0100 +Subject: [PATCH] Avoid returning CHM file entries that are "blank" because + they have embedded null bytes (cherry picked from commit + 8759da8db6ec9e866cb8eb143313f397f925bb4f) + +https://github.com/kyz/libmspack/commit/8759da8db6ec9e866cb8eb143313f397f925bb4f +--- + libmspack/mspack/chmd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/mspack/chmd.c b/mspack/chmd.c +index 014e71e..0f6c3a3 100644 +--- a/mspack/chmd.c ++++ b/mspack/chmd.c +@@ -447,14 +447,14 @@ static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh, + while (num_entries--) { + READ_ENCINT(name_len); + if (name_len > (unsigned int) (end - p)) goto chunk_end; +- /* consider blank filenames to be an error */ +- if (name_len == 0) goto chunk_end; + name = p; p += name_len; +- + READ_ENCINT(section); + READ_ENCINT(offset); + READ_ENCINT(length); + ++ /* ignore blank or one-char (e.g. "/") filenames we'd return as blank */ ++ if (name_len < 2 || !name[0] || !name[1]) continue; ++ + /* empty files and directory names are stored as a file entry at + * offset 0 with length 0. We want to keep empty files, but not + * directory names, which end with a "/" */ +-- +1.7.12.4 + diff --git a/CVE-2018-18586.patch b/CVE-2018-18586.patch new file mode 100644 index 0000000..0b84a24 --- /dev/null +++ b/CVE-2018-18586.patch @@ -0,0 +1,174 @@ +From 7cadd489698be117c47efcadd742651594429e6d Mon Sep 17 00:00:00 2001 +From: Stuart Caie +Date: Sat, 20 Oct 2018 19:06:32 +0100 +Subject: [PATCH] add anti "../" and leading slash protection to chmextract + +--- + libmspack/src/chmextract.c | 140 +++++-------------------------------- + 1 files changed, 17 insertions(+), 123 deletions(-) + +diff --git a/libmspack/src/chmextract.c b/libmspack/src/chmextract.c +index 1e03341..b535f0e 100644 +--- a/src/chmextract.c ++++ b/src/chmextract.c +@@ -25,8 +25,6 @@ + + mode_t user_umask; + +-#define FILENAME ".test.chmx" +- + /** + * Ensures that all directory components in a filepath exist. New directory + * components are created, if necessary. +@@ -51,126 +49,22 @@ static int ensure_filepath(char *path) { + return 1; + } + +-/** +- * Creates a UNIX filename from the internal CAB filename and the given +- * parameters. +- * +- * @param fname the internal CAB filename. +- * @param dir a directory path to prepend to the output filename. +- * @param lower if non-zero, filename should be made lower-case. +- * @param isunix if zero, MS-DOS path seperators are used in the internal +- * CAB filename. If non-zero, UNIX path seperators are used. +- * @param utf8 if non-zero, the internal CAB filename is encoded in UTF8. +- * @return a freshly allocated and created filename, or NULL if there was +- * not enough memory. +- * @see unix_path_seperators() +- */ +-static char *create_output_name(unsigned char *fname, unsigned char *dir, +- int lower, int isunix, int utf8) +-{ +- unsigned char *p, *name, c, *fe, sep, slash; +- unsigned int x; +- +- sep = (isunix) ? '/' : '\\'; /* the path-seperator */ +- slash = (isunix) ? '\\' : '/'; /* the other slash */ +- +- /* length of filename */ +- x = strlen((char *) fname); +- /* UTF8 worst case scenario: tolower() expands all chars from 1 to 3 bytes */ +- if (utf8) x *= 3; +- /* length of output directory */ +- if (dir) x += strlen((char *) dir); +- +- if (!(name = (unsigned char *) malloc(x + 2))) { +- fprintf(stderr, "out of memory!\n"); +- return NULL; +- } +- +- /* start with blank name */ +- *name = '\0'; +- +- /* add output directory if needed */ +- if (dir) { +- strcpy((char *) name, (char *) dir); +- strcat((char *) name, "/"); +- } +- +- /* remove leading slashes */ +- while (*fname == sep) fname++; +- +- /* copy from fi->filename to new name, converting MS-DOS slashes to UNIX +- * slashes as we go. Also lowercases characters if needed. +- */ +- p = &name[strlen((char *)name)]; +- fe = &fname[strlen((char *)fname)]; +- +- if (utf8) { +- /* UTF8 translates two-byte unicode characters into 1, 2 or 3 bytes. +- * %000000000xxxxxxx -> %0xxxxxxx +- * %00000xxxxxyyyyyy -> %110xxxxx %10yyyyyy +- * %xxxxyyyyyyzzzzzz -> %1110xxxx %10yyyyyy %10zzzzzz +- * +- * Therefore, the inverse is as follows: +- * First char: +- * 0x00 - 0x7F = one byte char +- * 0x80 - 0xBF = invalid +- * 0xC0 - 0xDF = 2 byte char (next char only 0x80-0xBF is valid) +- * 0xE0 - 0xEF = 3 byte char (next 2 chars only 0x80-0xBF is valid) +- * 0xF0 - 0xFF = invalid +- */ +- do { +- if (fname >= fe) { +- free(name); +- return NULL; +- } +- +- /* get next UTF8 char */ +- if ((c = *fname++) < 0x80) x = c; +- else { +- if ((c >= 0xC0) && (c < 0xE0)) { +- x = (c & 0x1F) << 6; +- x |= *fname++ & 0x3F; +- } +- else if ((c >= 0xE0) && (c < 0xF0)) { +- x = (c & 0xF) << 12; +- x |= (*fname++ & 0x3F) << 6; +- x |= *fname++ & 0x3F; +- } +- else x = '?'; +- } +- +- /* whatever is the path seperator -> '/' +- * whatever is the other slash -> '\\' +- * otherwise, if lower is set, the lowercase version */ +- if (x == sep) x = '/'; +- else if (x == slash) x = '\\'; +- else if (lower) x = (unsigned int) tolower((int) x); +- +- /* integer back to UTF8 */ +- if (x < 0x80) { +- *p++ = (unsigned char) x; +- } +- else if (x < 0x800) { +- *p++ = 0xC0 | (x >> 6); +- *p++ = 0x80 | (x & 0x3F); +- } +- else { +- *p++ = 0xE0 | (x >> 12); +- *p++ = 0x80 | ((x >> 6) & 0x3F); +- *p++ = 0x80 | (x & 0x3F); +- } +- } while (x); +- } +- else { +- /* regular non-utf8 version */ +- do { +- c = *fname++; +- if (c == sep) c = '/'; +- else if (c == slash) c = '\\'; +- else if (lower) c = (unsigned char) tolower((int) c); +- } while ((*p++ = c)); +- } +- return (char *) name; ++char *create_output_name(char *fname) { ++ char *out, *p; ++ if ((out = malloc(strlen(fname) + 1))) { ++ /* remove leading slashes */ ++ while (*fname == '/' || *fname == '\\') fname++; ++ /* if that removes all characters, just call it "x" */ ++ strcpy(out, (*fname) ? fname : "x"); ++ ++ /* change "../" to "xx/" */ ++ for (p = out; *p; p++) { ++ if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\\')) { ++ p[0] = p[1] = 'x'; ++ } ++ } ++ } ++ return out; + } + + static int sortfunc(const void *a, const void *b) { +@@ -205,7 +99,7 @@ int main(int argc, char *argv[]) { + qsort(f, numf, sizeof(struct mschmd_file *), &sortfunc); + + for (i = 0; i < numf; i++) { +- char *outname = create_output_name((unsigned char *)f[i]->filename,NULL,0,1,0); ++ char *outname = create_output_name(f[i]->filename); + printf("Extracting %s\n", outname); + ensure_filepath(outname); + if (chmd->extract(chmd, f[i], outname)) { diff --git a/libmspack.spec b/libmspack.spec index 072683c..6fefff7 100644 --- a/libmspack.spec +++ b/libmspack.spec @@ -1,6 +1,6 @@ Name: libmspack Version: 0.7 -Release: 0.1.4 +Release: 0.1.5 Summary: Library for CAB and related files compression and decompression License: LGPLv2.1 URL: http://www.cabextract.org.uk/libmspack/ @@ -9,6 +9,8 @@ Source0: https://github.com/kyz/libmspack/archive/v0.7alpha/%{name}-v0.7a Patch0: %{name}-0.4alpha-doc.patch Patch6000: CVE-2019-1010305.patch +Patch6001: CVE-2018-18585.patch +Patch6002: CVE-2018-18586.patch BuildRequires: doxygen gcc autoconf automake libtool @@ -77,6 +79,9 @@ cd .. %doc doc/html %changelog +* Sat Dec 21 2019 openEuler Buildteam - 0.7-0.1.5 +- Fix CVE-2018-18585 and CVE-2018-18586 + * Mon Aug 12 2019 zhuguodong - 0.7-0.1.4 - Type:bugfix - ID:NA