Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package mapserver to fix CVE-2021-32062 as reported in #988208. [ Reason ] Fix security issue. [ Impact ] Unfixed security issue. [ Tests ] Upstream CI. [ Risks ] Low, leaf package. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] 0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch is required as a dependency of 0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch. unblock mapserver/7.6.2-2
diff -Nru mapserver-7.6.2/debian/changelog mapserver-7.6.2/debian/changelog --- mapserver-7.6.2/debian/changelog 2020-12-09 06:01:02.000000000 +0100 +++ mapserver-7.6.2/debian/changelog 2021-05-08 07:12:18.000000000 +0200 @@ -1,3 +1,12 @@ +mapserver (7.6.2-2) unstable; urgency=high + + * Drop unused lintian overrides. + * Add upstream patches to fix CVE-2021-32062. + (closes: #988208) + * Update symbols file. + + -- Bas Couwenberg <sebas...@debian.org> Sat, 08 May 2021 07:12:18 +0200 + mapserver (7.6.2-1) unstable; urgency=medium * Update symbols for other architectures. diff -Nru mapserver-7.6.2/debian/libmapserver2.lintian-overrides mapserver-7.6.2/debian/libmapserver2.lintian-overrides --- mapserver-7.6.2/debian/libmapserver2.lintian-overrides 2020-08-06 05:34:57.000000000 +0200 +++ mapserver-7.6.2/debian/libmapserver2.lintian-overrides 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -# Cannot easily be fixed -file-references-package-build-path * - diff -Nru mapserver-7.6.2/debian/libmapserver2.symbols mapserver-7.6.2/debian/libmapserver2.symbols --- mapserver-7.6.2/debian/libmapserver2.symbols 2020-12-09 06:00:39.000000000 +0100 +++ mapserver-7.6.2/debian/libmapserver2.symbols 2021-05-08 07:11:08.000000000 +0200 @@ -945,6 +945,7 @@ msCSVJoinPrepare@Base 6.2.1 msCairoCleanup@Base 6.2.1 msCalculateScale@Base 6.2.1 + msCaseEvalRegex@Base 7.6.2 msCaseReplaceSubstring@Base 6.2.1 msCheckLabelMinDistance@Base 7.0.0 msCheckParentPointer@Base 6.2.1 @@ -1418,6 +1419,7 @@ msIsGlyphASpace@Base 7.2.0 msIsLayerQueryable@Base 6.2.1 msIsOuterRing@Base 6.2.1 + msIsValidRegex@Base 7.6.2 msIsXMLTagValid@Base 6.2.1 msItemInGroups@Base 6.2.1 msJoinClose@Base 6.2.1 diff -Nru mapserver-7.6.2/debian/mapserver-bin.lintian-overrides mapserver-7.6.2/debian/mapserver-bin.lintian-overrides --- mapserver-7.6.2/debian/mapserver-bin.lintian-overrides 2020-08-06 05:34:57.000000000 +0200 +++ mapserver-7.6.2/debian/mapserver-bin.lintian-overrides 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -# Cannot easily be fixed -file-references-package-build-path * - diff -Nru mapserver-7.6.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch mapserver-7.6.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch --- mapserver-7.6.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch 1970-01-01 01:00:00.000000000 +0100 +++ mapserver-7.6.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch 2021-05-08 07:10:49.000000000 +0200 @@ -0,0 +1,161 @@ +Description: Address flaw in CGI mapfile loading that makes it possible to bypass security controls. +Author: Even Rouault <even.roua...@spatialys.com> +Origin: https://github.com/MapServer/MapServer/commit/927ac97cb9ece305306b5ab2b5600d3afe8c1732 +Bug: https://github.com/MapServer/MapServer/issues/6313 +Bug-Debian: https://bugs.debian.org/988208 + +--- a/mapfile.c ++++ b/mapfile.c +@@ -97,6 +97,16 @@ int msValidateParameter(const char *valu + return(MS_FAILURE); + } + ++int msIsValidRegex(const char* e) { ++ ms_regex_t re; ++ if(ms_regcomp(&re, e, MS_REG_EXTENDED|MS_REG_NOSUB) != 0) { ++ msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); ++ return(MS_FALSE); ++ } ++ ms_regfree(&re); ++ return MS_TRUE; ++} ++ + int msEvalRegex(const char *e, const char *s) + { + ms_regex_t re; +@@ -107,6 +117,26 @@ int msEvalRegex(const char *e, const cha + msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); + return(MS_FALSE); + } ++ ++ if(ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ ++ ms_regfree(&re); ++ return(MS_FALSE); ++ } ++ ms_regfree(&re); ++ ++ return(MS_TRUE); ++} ++ ++int msCaseEvalRegex(const char *e, const char *s) ++{ ++ ms_regex_t re; ++ ++ if(!e || !s) return(MS_FALSE); ++ ++ if(ms_regcomp(&re, e, MS_REG_EXTENDED|MS_REG_ICASE|MS_REG_NOSUB) != 0) { ++ msSetError(MS_REGEXERR, "Failed to compile expression (%s).", "msEvalRegex()", e); ++ return(MS_FALSE); ++ } + + if(ms_regexec(&re, s, 0, NULL, 0) != 0) { /* no match */ + ms_regfree(&re); +--- a/mapserv.c ++++ b/mapserv.c +@@ -166,7 +166,8 @@ int main(int argc, char *argv[]) + + /* push high-value ENV vars into the CPL global config - primarily for IIS/FastCGI */ + const char* const apszEnvVars[] = { +- "CURL_CA_BUNDLE", "MS_MAPFILE", "MS_MAP_NO_PATH", "MS_MAP_PATTERN", ++ "CURL_CA_BUNDLE", "MS_MAPFILE", "MS_MAP_NO_PATH", "MS_MAP_PATTERN", "MS_MAP_ENV_PATTERN", ++ "MS_MAP_BAD_PATTERN", "MS_MAP_ENV_BAD_PATTERN", + NULL /* guard */ }; + for( int i = 0; apszEnvVars[i] != NULL; ++i ) { + const char* value = getenv(apszEnvVars[i]); +--- a/mapserver.h ++++ b/mapserver.h +@@ -2159,7 +2159,9 @@ void msPopulateTextSymbolForLabelAndStri + MS_DLL_EXPORT char *msWriteReferenceMapToString(referenceMapObj *ref); + MS_DLL_EXPORT char *msWriteLegendToString(legendObj *legend); + MS_DLL_EXPORT char *msWriteClusterToString(clusterObj *cluster); ++ MS_DLL_EXPORT int msIsValidRegex(const char* e); + MS_DLL_EXPORT int msEvalRegex(const char *e, const char *s); ++ MS_DLL_EXPORT int msCaseEvalRegex(const char *e, const char *s); + #ifdef USE_MSFREE + MS_DLL_EXPORT void msFree(void *p); + #else +--- a/mapservutil.c ++++ b/mapservutil.c +@@ -199,41 +199,67 @@ mapObj *msCGILoadMap(mapservObj *mapserv + int i, j; + mapObj *map = NULL; + ++ const char *ms_map_bad_pattern_default = "[/\\]{2}|[/\\]?\\.+[/\\]|,"; ++ const char *ms_map_env_bad_pattern_default = "^(AUTH_.*|CERT_.*|CONTENT_(LENGTH|TYPE)|DOCUMENT_(ROOT|URI)|GATEWAY_INTERFACE|HTTP.*|QUERY_STRING|PATH_(INFO|TRANSLATED)|REMOTE_.*|REQUEST_(METHOD|URI)|SCRIPT_(FILENAME|NAME)|SERVER_.*)"; ++ ++ int ms_mapfile_tainted = MS_TRUE; + const char *ms_mapfile = CPLGetConfigOption("MS_MAPFILE", NULL); ++ + const char *ms_map_no_path = CPLGetConfigOption("MS_MAP_NO_PATH", NULL); + const char *ms_map_pattern = CPLGetConfigOption("MS_MAP_PATTERN", NULL); ++ const char *ms_map_env_pattern = CPLGetConfigOption("MS_MAP_ENV_PATTERN", NULL); ++ ++ const char *ms_map_bad_pattern = CPLGetConfigOption("MS_MAP_BAD_PATTERN", NULL); ++ if(ms_map_bad_pattern == NULL) ms_map_bad_pattern = ms_map_bad_pattern_default; ++ ++ const char *ms_map_env_bad_pattern = CPLGetConfigOption("MS_MAP_ENV_BAD_PATTERN", NULL); ++ if(ms_map_env_bad_pattern == NULL) ms_map_env_bad_pattern = ms_map_env_bad_pattern_default; + + for(i=0; i<mapserv->request->NumParams; i++) /* find the mapfile parameter first */ + if(strcasecmp(mapserv->request->ParamNames[i], "map") == 0) break; + + if(i == mapserv->request->NumParams) { +- if(ms_mapfile != NULL) { +- map = msLoadMap(ms_mapfile,NULL); +- } else { ++ if(ms_mapfile == NULL) { + msSetError(MS_WEBERR, "CGI variable \"map\" is not set.", "msCGILoadMap()"); /* no default, outta here */ + return NULL; + } ++ ms_mapfile_tainted = MS_FALSE; + } else { +- if(getenv(mapserv->request->ParamValues[i])) /* an environment variable references the actual file to use */ +- map = msLoadMap(getenv(mapserv->request->ParamValues[i]), NULL); +- else { +- /* by here we know the request isn't for something in an environment variable */ +- if(ms_map_no_path != NULL) { +- msSetError(MS_WEBERR, "Mapfile not found in environment variables and this server is not configured for full paths.", "msCGILoadMap()"); ++ if(getenv(mapserv->request->ParamValues[i])) { /* an environment variable references the actual file to use */ ++ /* validate env variable name */ ++ if(msIsValidRegex(ms_map_env_bad_pattern) == MS_FALSE || msCaseEvalRegex(ms_map_env_bad_pattern, mapserv->request->ParamValues[i]) == MS_TRUE) { ++ msSetError(MS_WEBERR, "CGI variable \"map\" fails to validate.", "msCGILoadMap()"); + return NULL; + } +- +- if(ms_map_pattern != NULL && msEvalRegex(ms_map_pattern, mapserv->request->ParamValues[i]) != MS_TRUE) { +- msSetError(MS_WEBERR, "Parameter 'map' value fails to validate.", "msCGILoadMap()"); ++ if(ms_map_env_pattern != NULL && msEvalRegex(ms_map_env_pattern, mapserv->request->ParamValues[i]) != MS_TRUE) { ++ msSetError(MS_WEBERR, "CGI variable \"map\" fails to validate.", "msCGILoadMap()"); ++ return NULL; ++ } ++ ms_mapfile = getenv(mapserv->request->ParamValues[i]); ++ } else { ++ /* by now we know the request isn't for something in an environment variable */ ++ if(ms_map_no_path != NULL) { ++ msSetError(MS_WEBERR, "CGI variable \"map\" not found in environment and this server is not configured for full paths.", "msCGILoadMap()"); + return NULL; + } ++ ms_mapfile = mapserv->request->ParamValues[i]; ++ } ++ } + +- /* ok to try to load now */ +- map = msLoadMap(mapserv->request->ParamValues[i], NULL); ++ /* validate ms_mapfile if tainted */ ++ if(ms_mapfile_tainted == MS_TRUE) { ++ if(msIsValidRegex(ms_map_bad_pattern) == MS_FALSE || msEvalRegex(ms_map_bad_pattern, ms_mapfile) == MS_TRUE) { ++ msSetError(MS_WEBERR, "CGI variable \"map\" fails to validate.", "msCGILoadMap()"); ++ return NULL; ++ } ++ if(ms_map_pattern != NULL && msEvalRegex(ms_map_pattern, ms_mapfile) != MS_TRUE) { ++ msSetError(MS_WEBERR, "CGI variable \"map\" fails to validate.", "msCGILoadMap()"); ++ return NULL; + } + } +- + ++ /* ok to try to load now */ ++ map = msLoadMap(ms_mapfile, NULL); + if(!map) return NULL; + + if(!msLookupHashTable(&(map->web.validation), "immutable")) { diff -Nru mapserver-7.6.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch mapserver-7.6.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch --- mapserver-7.6.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch 1970-01-01 01:00:00.000000000 +0100 +++ mapserver-7.6.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch 2021-05-08 07:10:49.000000000 +0200 @@ -0,0 +1,107 @@ +Description: Use CPLSetConfigOption/CPLGetConfigOption for some CGI/FastCGI-related env vars. + Push a few high-value env vars into CPL config and then reference that instead of the env (mostly for IIS/FastCGI). +Author: Steve Lime <steve.l...@state.mn.us> +Origin: https://github.com/MapServer/MapServer/commit/b128dace3ec3e61bf063f7285d1279e9f9fd9e28 +Bug: https://github.com/MapServer/MapServer/pull/6304 + +--- a/maphttp.c ++++ b/maphttp.c +@@ -39,7 +39,7 @@ + #include "mapthread.h" + #include "mapows.h" + +- ++#include "cpl_conv.h" + + #include <time.h> + #ifndef _WIN32 +@@ -471,7 +471,7 @@ int msHTTPExecuteRequests(httpRequestObj + * If set then the value is the full path to the ca-bundle.crt file + * e.g. CURL_CA_BUNDLE=/usr/local/share/curl/curl-ca-bundle.crt + */ +- pszCurlCABundle = getenv("CURL_CA_BUNDLE"); ++ pszCurlCABundle = CPLGetConfigOption("CURL_CA_BUNDLE", NULL); + + if (debug) { + msDebug("HTTP: Starting to prepare HTTP requests.\n"); +--- a/mapserv.c ++++ b/mapserv.c +@@ -43,6 +43,8 @@ + #include "mapio.h" + #include "maptime.h" + ++#include "cpl_conv.h" ++ + #ifndef WIN32 + #include <signal.h> + #endif +@@ -162,6 +164,15 @@ int main(int argc, char *argv[]) + if(msGetGlobalDebugLevel() >= MS_DEBUGLEVEL_TUNING) + msGettimeofday(&execstarttime, NULL); + ++ /* push high-value ENV vars into the CPL global config - primarily for IIS/FastCGI */ ++ const char* const apszEnvVars[] = { ++ "CURL_CA_BUNDLE", "MS_MAPFILE", "MS_MAP_NO_PATH", "MS_MAP_PATTERN", ++ NULL /* guard */ }; ++ for( int i = 0; apszEnvVars[i] != NULL; ++i ) { ++ const char* value = getenv(apszEnvVars[i]); ++ if(value) CPLSetConfigOption(apszEnvVars[i], value); ++ } ++ + /* -------------------------------------------------------------------- */ + /* Process arguments. In normal use as a cgi-bin there are no */ + /* commandline switches, but we provide a few for test/debug */ +--- a/mapserv.h ++++ b/mapserv.h +@@ -41,6 +41,7 @@ + #include "maptile.h" + + #include "cgiutil.h" ++ + /* + ** Defines + */ +--- a/mapservutil.c ++++ b/mapservutil.c +@@ -33,6 +33,8 @@ + #include "maptime.h" + #include "mapows.h" + ++#include "cpl_conv.h" ++ + /* + ** Enumerated types, keep the query modes in sequence and at the end of the enumeration (mode enumeration is in maptemplate.h). + */ +@@ -197,12 +199,15 @@ mapObj *msCGILoadMap(mapservObj *mapserv + int i, j; + mapObj *map = NULL; + ++ const char *ms_mapfile = CPLGetConfigOption("MS_MAPFILE", NULL); ++ const char *ms_map_no_path = CPLGetConfigOption("MS_MAP_NO_PATH", NULL); ++ const char *ms_map_pattern = CPLGetConfigOption("MS_MAP_PATTERN", NULL); ++ + for(i=0; i<mapserv->request->NumParams; i++) /* find the mapfile parameter first */ + if(strcasecmp(mapserv->request->ParamNames[i], "map") == 0) break; + + if(i == mapserv->request->NumParams) { +- char *ms_mapfile = getenv("MS_MAPFILE"); +- if(ms_mapfile) { ++ if(ms_mapfile != NULL) { + map = msLoadMap(ms_mapfile,NULL); + } else { + msSetError(MS_WEBERR, "CGI variable \"map\" is not set.", "msCGILoadMap()"); /* no default, outta here */ +@@ -213,12 +218,12 @@ mapObj *msCGILoadMap(mapservObj *mapserv + map = msLoadMap(getenv(mapserv->request->ParamValues[i]), NULL); + else { + /* by here we know the request isn't for something in an environment variable */ +- if(getenv("MS_MAP_NO_PATH")) { ++ if(ms_map_no_path != NULL) { + msSetError(MS_WEBERR, "Mapfile not found in environment variables and this server is not configured for full paths.", "msCGILoadMap()"); + return NULL; + } + +- if(getenv("MS_MAP_PATTERN") && msEvalRegex(getenv("MS_MAP_PATTERN"), mapserv->request->ParamValues[i]) != MS_TRUE) { ++ if(ms_map_pattern != NULL && msEvalRegex(ms_map_pattern, mapserv->request->ParamValues[i]) != MS_TRUE) { + msSetError(MS_WEBERR, "Parameter 'map' value fails to validate.", "msCGILoadMap()"); + return NULL; + } diff -Nru mapserver-7.6.2/debian/patches/series mapserver-7.6.2/debian/patches/series --- mapserver-7.6.2/debian/patches/series 2020-12-08 05:49:56.000000000 +0100 +++ mapserver-7.6.2/debian/patches/series 2021-05-08 07:10:49.000000000 +0200 @@ -1,3 +1,5 @@ perl-mapscript-install.patch java-hardening.patch interpreter-path.path +0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch +0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch