--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: buster-pu: package mapserver/7.2.2-2
- From: Bas Couwenberg <sebastic@xs4all.nl>
- Date: Sat, 08 May 2021 08:08:26 +0200
- Message-id: <162045410642.355215.3208055138451267659.reportbug@osiris.linuxminded.xs4all.nl>
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@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 <sebastic@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.lime@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 <sethg@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
--- End Message ---