[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#988225: buster-pu: package mapserver/7.2.2-2



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

Reply to: