Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu
CVE-2021-32062 as reported in #988208 also affects version 7.2 in buster. [ Reason ] Fix CVE-2021-32062. [ Impact ] Unfixed security issue. [ Tests ] Upstream CI. [ Risks ] Low. [ 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 (old)stable [ ] the issue is verified as fixed in unstable [ Changes ] A different VCS branch is used for buster, for which the packaging is updated. Both upstream patches are required to fix CVE-2021-32062. 0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch is a dependency of 0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch. The upstream changes introduce two symbols used to fix the issue, for which the symbols file is updated. lintian also reported a spelling error, which is left unfixed. [ Other info ] The fix for unstable is pending pre-approval, see: #988224. Kind Regards, Bas
diff -Nru mapserver-7.2.2/debian/changelog mapserver-7.2.2/debian/changelog --- mapserver-7.2.2/debian/changelog 2019-02-20 05:43:10.000000000 +0100 +++ mapserver-7.2.2/debian/changelog 2021-05-08 07:35:27.000000000 +0200 @@ -1,3 +1,12 @@ +mapserver (7.2.2-2) buster; urgency=high + + * Update branch in gbp.conf & Vcs-Git URL. + * Add upstream patches to fix CVE-2021-32062. + (closes: 988208) + * Update symbols file. + + -- Bas Couwenberg <sebas...@debian.org> Sat, 08 May 2021 07:35:27 +0200 + mapserver (7.2.2-1) unstable; urgency=medium * Update symbols for other architectures. diff -Nru mapserver-7.2.2/debian/control mapserver-7.2.2/debian/control --- mapserver-7.2.2/debian/control 2018-12-25 22:37:35.000000000 +0100 +++ mapserver-7.2.2/debian/control 2021-05-08 07:30:00.000000000 +0200 @@ -49,7 +49,7 @@ Build-Conflicts: libcurl3-openssl-dev Standards-Version: 4.3.0 Vcs-Browser: https://salsa.debian.org/debian-gis-team/mapserver -Vcs-Git: https://salsa.debian.org/debian-gis-team/mapserver.git +Vcs-Git: https://salsa.debian.org/debian-gis-team/mapserver.git -b buster Homepage: http://www.mapserver.org XS-Ruby-Versions: all diff -Nru mapserver-7.2.2/debian/gbp.conf mapserver-7.2.2/debian/gbp.conf --- mapserver-7.2.2/debian/gbp.conf 2018-10-07 09:10:30.000000000 +0200 +++ mapserver-7.2.2/debian/gbp.conf 2021-05-08 07:29:50.000000000 +0200 @@ -6,7 +6,7 @@ # The default name for the Debian branch is "master". # Change it if the name is different (for instance, "debian/unstable"). -debian-branch = master +debian-branch = buster # git-import-orig uses the following names for the upstream tags. # Change the value if you are not using git-import-orig diff -Nru mapserver-7.2.2/debian/libmapserver2.symbols mapserver-7.2.2/debian/libmapserver2.symbols --- mapserver-7.2.2/debian/libmapserver2.symbols 2019-02-20 05:42:33.000000000 +0100 +++ mapserver-7.2.2/debian/libmapserver2.symbols 2021-05-08 07:35:27.000000000 +0200 @@ -953,6 +953,7 @@ msCSVJoinPrepare@Base 6.2.1 msCairoCleanup@Base 6.2.1 msCalculateScale@Base 6.2.1 + msCaseEvalRegex@Base 7.2.2 msCaseReplaceSubstring@Base 6.2.1 msCheckLabelMinDistance@Base 7.0.0 msCheckParentPointer@Base 6.2.1 @@ -1421,6 +1422,7 @@ msIsGlyphASpace@Base 7.2.0 msIsLayerQueryable@Base 6.2.1 msIsOuterRing@Base 6.2.1 + msIsValidRegex@Base 7.2.2 msIsXMLTagValid@Base 6.2.1 msItemInGroups@Base 6.2.1 msJoinClose@Base 6.2.1 diff -Nru mapserver-7.2.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch mapserver-7.2.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch --- mapserver-7.2.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.2.2/debian/patches/0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch 2021-05-08 07:34:08.000000000 +0200 @@ -0,0 +1,161 @@ +Description: Address flaw in CGI mapfile loading that makes it possible to bypass security controls. +Author: Steve Lime <steve.l...@state.mn.us> +Origin: https://github.com/MapServer/MapServer/commit/7db7cbb26b6bc6e651db268e9536836a56e6825a +Bug: https://github.com/MapServer/MapServer/issues/6313 +Bug-Debian: https://bugs.debian.org/988208 + +--- a/mapfile.c ++++ b/mapfile.c +@@ -104,6 +104,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; +@@ -114,6 +124,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 +@@ -160,7 +160,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 +@@ -2139,7 +2139,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.2.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch mapserver-7.2.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch --- mapserver-7.2.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch 1970-01-01 01:00:00.000000000 +0100 +++ mapserver-7.2.2/debian/patches/0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch 2021-05-08 07:32:55.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: Seth G <se...@geographika.co.uk> +Origin: https://github.com/MapServer/MapServer/commit/c079fb110b335d0ece78049ba7bc5d1d67023003 +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 +@@ -36,6 +36,8 @@ + #include "mapio.h" + #include "maptime.h" + ++#include "cpl_conv.h" ++ + #ifndef WIN32 + #include <signal.h> + #endif +@@ -156,6 +158,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.2.2/debian/patches/series mapserver-7.2.2/debian/patches/series --- mapserver-7.2.2/debian/patches/series 2019-02-19 19:16:01.000000000 +0100 +++ mapserver-7.2.2/debian/patches/series 2021-05-08 07:31:42.000000000 +0200 @@ -2,3 +2,5 @@ perl-mapscript-install.patch ruby-mapscript-install.patch java-hardening.patch +0001-Use-CPLSetConfigOption-CPLGetConfigOption-for-some-C.patch +0001-Address-flaw-in-CGI-mapfile-loading-that-makes-it-po.patch