Hello community, here is the log from the commit of package zziplib for openSUSE:Factory checked in at 2018-10-11 11:42:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/zziplib (Old) and /work/SRC/openSUSE:Factory/.zziplib.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "zziplib" Thu Oct 11 11:42:49 2018 rev:32 rq:639943 version:0.13.69 Changes: -------- --- /work/SRC/openSUSE:Factory/zziplib/zziplib.changes 2018-09-20 11:39:36.932921486 +0200 +++ /work/SRC/openSUSE:Factory/.zziplib.new/zziplib.changes 2018-10-11 11:42:53.342982522 +0200 @@ -1,0 +2,6 @@ +Thu Oct 4 08:14:00 UTC 2018 - [email protected] + +- Remove any "../" components from pathnames of extracted files. + [bsc#1110687, CVE-2018-17828, CVE-2018-17828.patch] + +------------------------------------------------------------------- New: ---- CVE-2018-17828.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ zziplib.spec ++++++ --- /var/tmp/diff_new_pack.KQQvMN/_old 2018-10-11 11:42:54.206981422 +0200 +++ /var/tmp/diff_new_pack.KQQvMN/_new 2018-10-11 11:42:54.206981422 +0200 @@ -21,7 +21,7 @@ Version: 0.13.69 Release: 0 Summary: ZIP Compression Library -License: LGPL-2.1-or-later +License: LGPL-2.1+ Group: Development/Libraries/C and C++ Url: http://zziplib.sourceforge.net Source0: https://github.com/gdraheim/zziplib/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz @@ -32,6 +32,7 @@ Patch3: CVE-2018-7726.patch Patch4: CVE-2018-7725.patch Patch5: CVE-2018-16548.patch +Patch6: CVE-2018-17828.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool @@ -71,6 +72,7 @@ %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 # do not bother with html docs saving us python2 dependency sed -i -e 's:docs ::g' Makefile.am ++++++ CVE-2018-17828.patch ++++++ Index: zziplib-0.13.69/bins/unzzipcat-mem.c =================================================================== --- zziplib-0.13.69.orig/bins/unzzipcat-mem.c +++ zziplib-0.13.69/bins/unzzipcat-mem.c @@ -58,6 +58,48 @@ static void unzzip_mem_disk_cat_file(ZZI } } +/* + * NAME: remove_dotdotslash + * PURPOSE: To remove any "../" components from the given pathname + * ARGUMENTS: path: path name with maybe "../" components + * RETURNS: Nothing, "path" is modified in-place + * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! + * Also, "path" is not used after creating it. + * So modifying "path" in-place is safe to do. + */ +static inline void +remove_dotdotslash(char *path) +{ + /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ + char *dotdotslash; + int warned = 0; + + dotdotslash = path; + while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) + { + /* + * Remove only if at the beginning of the pathname ("../path/name") + * or when preceded by a slash ("path/../name"), + * otherwise not ("path../name..")! + */ + if (dotdotslash == path || dotdotslash[-1] == '/') + { + char *src, *dst; + if (!warned) + { + /* Note: the first time through the pathname is still intact */ + fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); + warned = 1; + } + /* We cannot use strcpy(), as there "The strings may not overlap" */ + for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) + ; + } + else + dotdotslash +=3; /* skip this instance to prevent infinite loop */ + } +} + static void makedirs(const char* name) { char* p = strrchr(name, '/'); @@ -75,6 +117,16 @@ static void makedirs(const char* name) static FILE* create_fopen(char* name, char* mode, int subdirs) { + char *name_stripped; + FILE *fp; + int mustfree = 0; + + if ((name_stripped = strdup(name)) != NULL) + { + remove_dotdotslash(name_stripped); + name = name_stripped; + mustfree = 1; + } if (subdirs) { char* p = strrchr(name, '/'); @@ -84,7 +136,10 @@ static FILE* create_fopen(char* name, ch free (dir_name); } } - return fopen(name, mode); + fp = fopen(name, mode); + if (mustfree) + free(name_stripped); + return fp; } static int unzzip_cat (int argc, char ** argv, int extract) Index: zziplib-0.13.69/bins/unzzipcat-big.c =================================================================== --- zziplib-0.13.69.orig/bins/unzzipcat-big.c +++ zziplib-0.13.69/bins/unzzipcat-big.c @@ -53,6 +53,48 @@ static void unzzip_cat_file(FILE* disk, } } +/* + * NAME: remove_dotdotslash + * PURPOSE: To remove any "../" components from the given pathname + * ARGUMENTS: path: path name with maybe "../" components + * RETURNS: Nothing, "path" is modified in-place + * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! + * Also, "path" is not used after creating it. + * So modifying "path" in-place is safe to do. + */ +static inline void +remove_dotdotslash(char *path) +{ + /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ + char *dotdotslash; + int warned = 0; + + dotdotslash = path; + while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) + { + /* + * Remove only if at the beginning of the pathname ("../path/name") + * or when preceded by a slash ("path/../name"), + * otherwise not ("path../name..")! + */ + if (dotdotslash == path || dotdotslash[-1] == '/') + { + char *src, *dst; + if (!warned) + { + /* Note: the first time through the pathname is still intact */ + fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); + warned = 1; + } + /* We cannot use strcpy(), as there "The strings may not overlap" */ + for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) + ; + } + else + dotdotslash +=3; /* skip this instance to prevent infinite loop */ + } +} + static void makedirs(const char* name) { char* p = strrchr(name, '/'); @@ -70,6 +112,16 @@ static void makedirs(const char* name) static FILE* create_fopen(char* name, char* mode, int subdirs) { + char *name_stripped; + FILE *fp; + int mustfree = 0; + + if ((name_stripped = strdup(name)) != NULL) + { + remove_dotdotslash(name_stripped); + name = name_stripped; + mustfree = 1; + } if (subdirs) { char* p = strrchr(name, '/'); @@ -79,7 +131,10 @@ static FILE* create_fopen(char* name, ch free (dir_name); } } - return fopen(name, mode); + fp = fopen(name, mode); + if (mustfree) + free(name_stripped); + return fp; } Index: zziplib-0.13.69/bins/unzzipcat-mix.c =================================================================== --- zziplib-0.13.69.orig/bins/unzzipcat-mix.c +++ zziplib-0.13.69/bins/unzzipcat-mix.c @@ -69,6 +69,48 @@ static void unzzip_cat_file(ZZIP_DIR* di } } +/* + * NAME: remove_dotdotslash + * PURPOSE: To remove any "../" components from the given pathname + * ARGUMENTS: path: path name with maybe "../" components + * RETURNS: Nothing, "path" is modified in-place + * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! + * Also, "path" is not used after creating it. + * So modifying "path" in-place is safe to do. + */ +static inline void +remove_dotdotslash(char *path) +{ + /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ + char *dotdotslash; + int warned = 0; + + dotdotslash = path; + while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) + { + /* + * Remove only if at the beginning of the pathname ("../path/name") + * or when preceded by a slash ("path/../name"), + * otherwise not ("path../name..")! + */ + if (dotdotslash == path || dotdotslash[-1] == '/') + { + char *src, *dst; + if (!warned) + { + /* Note: the first time through the pathname is still intact */ + fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); + warned = 1; + } + /* We cannot use strcpy(), as there "The strings may not overlap" */ + for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) + ; + } + else + dotdotslash +=3; /* skip this instance to prevent infinite loop */ + } +} + static void makedirs(const char* name) { char* p = strrchr(name, '/'); @@ -86,6 +128,16 @@ static void makedirs(const char* name) static FILE* create_fopen(char* name, char* mode, int subdirs) { + char *name_stripped; + FILE *fp; + int mustfree = 0; + + if ((name_stripped = strdup(name)) != NULL) + { + remove_dotdotslash(name_stripped); + name = name_stripped; + mustfree = 1; + } if (subdirs) { char* p = strrchr(name, '/'); @@ -95,7 +147,10 @@ static FILE* create_fopen(char* name, ch free (dir_name); } } - return fopen(name, mode); + fp = fopen(name, mode); + if (mustfree) + free(name_stripped); + return fp; } static int unzzip_cat (int argc, char ** argv, int extract) Index: zziplib-0.13.69/bins/unzzipcat-zip.c =================================================================== --- zziplib-0.13.69.orig/bins/unzzipcat-zip.c +++ zziplib-0.13.69/bins/unzzipcat-zip.c @@ -69,6 +69,48 @@ static void unzzip_cat_file(ZZIP_DIR* di } } +/* + * NAME: remove_dotdotslash + * PURPOSE: To remove any "../" components from the given pathname + * ARGUMENTS: path: path name with maybe "../" components + * RETURNS: Nothing, "path" is modified in-place + * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! + * Also, "path" is not used after creating it. + * So modifying "path" in-place is safe to do. + */ +static inline void +remove_dotdotslash(char *path) +{ + /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ + char *dotdotslash; + int warned = 0; + + dotdotslash = path; + while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) + { + /* + * Remove only if at the beginning of the pathname ("../path/name") + * or when preceded by a slash ("path/../name"), + * otherwise not ("path../name..")! + */ + if (dotdotslash == path || dotdotslash[-1] == '/') + { + char *src, *dst; + if (!warned) + { + /* Note: the first time through the pathname is still intact */ + fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); + warned = 1; + } + /* We cannot use strcpy(), as there "The strings may not overlap" */ + for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) + ; + } + else + dotdotslash +=3; /* skip this instance to prevent infinite loop */ + } +} + static void makedirs(const char* name) { char* p = strrchr(name, '/'); @@ -86,6 +128,16 @@ static void makedirs(const char* name) static FILE* create_fopen(char* name, char* mode, int subdirs) { + char *name_stripped; + FILE *fp; + int mustfree = 0; + + if ((name_stripped = strdup(name)) != NULL) + { + remove_dotdotslash(name_stripped); + name = name_stripped; + mustfree = 1; + } if (subdirs) { char* p = strrchr(name, '/'); @@ -95,7 +147,10 @@ static FILE* create_fopen(char* name, ch free (dir_name); } } - return fopen(name, mode); + fp = fopen(name, mode); + if (mustfree) + free(name_stripped); + return fp; } static int unzzip_cat (int argc, char ** argv, int extract)
