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

Bug#988224: unblock: mapserver/7.6.2-2 (pre-approval)



Control: tags -1 moreinfo confirmed

On 2021-05-08 07:29:01 +0200, Bas Couwenberg wrote:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@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 <sebastic@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

This version is not high enough. The symbols need to be marked as
requiring 7.6.2-2~

Please remove the moreinfo tag once that fixed version is available in
unstable.

Cheers

>   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.rouault@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.lime@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


-- 
Sebastian Ramacher

Attachment: signature.asc
Description: PGP signature


Reply to: