Hello community,

here is the log from the commit of package autofs for openSUSE:Factory checked 
in at 2015-03-05 15:34:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/autofs (Old)
 and      /work/SRC/openSUSE:Factory/.autofs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "autofs"

Changes:
--------
--- /work/SRC/openSUSE:Factory/autofs/autofs.changes    2015-02-20 
12:00:52.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.autofs.new/autofs.changes       2015-03-05 
18:15:33.000000000 +0100
@@ -1,0 +2,9 @@
+Tue Mar  3 10:56:48 CET 2015 - mszer...@suse.cz
+
+- prevent potential privilege escalation via interpreter load path
+  for program-based automount maps, add the following patches:
+  autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch
+  autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch
+  (bnc#917977 CVE-2014-8169)
+
+-------------------------------------------------------------------

New:
----
  autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch
  autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ autofs.spec ++++++
--- /var/tmp/diff_new_pack.hvUEVj/_old  2015-03-05 18:15:33.000000000 +0100
+++ /var/tmp/diff_new_pack.hvUEVj/_new  2015-03-05 18:15:33.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package autofs
 #
-# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -80,6 +80,8 @@
 # PATCH-FIX-UPSTREAM autofs-5.1.0-task-use-after-free.patch [bnc#727392]
 Patch82:        autofs-5.0.9-task-use-after-free.patch
 Patch83:        
autofs-5.1.0-dont-pass-sloppy-option-for-other-than-nfs-mounts.patch
+Patch84:        autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch
+Patch85:        
autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch
 # PATCH-FIX-OPENSUSE autofs-5.0.9-suse-auto_master_default.patch
 Patch100:       autofs-5.0.9-suse-auto_master_default.patch
 # PATCH-EXTEND-OPENSUSE autofs-5.0.8-dbus-udisks-monitor.patch
@@ -108,6 +110,8 @@
 #
 %patch82 -p1
 %patch83 -p1
+%patch84 -p1
+%patch85 -p1
 %patch100 -p1
 %patch102 -p0 -b .udisks
 %patch200 -p1

++++++ autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch ++++++
autofs-5.1.0 - add a prefix to program map stdvars

From: Ian Kent <ik...@redhat.com>

When a program map uses an interpreted languages like python it's
possible to load and execute arbitray code from a user home directory.
This is because the standard environment variables are used to locate
and load modules when using these languages.

To avoid that we need to add a prefix to these environment names so
they aren't used for this purpose. The prefix used is "AUTOFS_" and
is not configurable.
---
 include/mounts.h         |    4 +-
 lib/mounts.c             |   84 +++++++++++++++++++++++++++++++++++++++--------
 modules/lookup_program.c |    2 -
 modules/parse_sun.c      |    8 ++--
 4 files changed, 77 insertions(+), 21 deletions(-)

--- a/include/mounts.h
+++ b/include/mounts.h
@@ -87,8 +87,8 @@ extern unsigned int nfs_mount_uses_strin
 
 struct amd_entry;
 
-struct substvar *addstdenv(struct substvar *sv);
-struct substvar *removestdenv(struct substvar *sv);
+struct substvar *addstdenv(struct substvar *sv, const char *prefix);
+struct substvar *removestdenv(struct substvar *sv, const char *prefix);
 void add_std_amd_vars(struct substvar *sv);
 void remove_std_amd_vars(void);
 struct amd_entry *new_amd_entry(const struct substvar *sv);
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -32,6 +32,7 @@
 
 #define MAX_OPTIONS_LEN                80
 #define MAX_MNT_NAME_LEN       30
+#define MAX_ENV_NAME           15
 
 #define EBUFSIZ 1024
 
@@ -316,7 +317,61 @@ int check_nfs_mount_version(struct nfs_m
 }
 #endif
 
-struct substvar *addstdenv(struct substvar *sv)
+static char *set_env_name(const char *prefix, const char *name, char *buf)
+{
+       size_t len;
+
+       len = strlen(name);
+       if (prefix)
+               len += strlen(prefix);
+       len++;
+
+       if (len > MAX_ENV_NAME)
+               return NULL;
+
+       if (!prefix)
+               strcpy(buf, name);
+       else {
+               strcpy(buf, prefix);
+               strcat(buf, name);
+       }
+       return buf;
+}
+
+static struct substvar *do_macro_addvar(struct substvar *list,
+                                       const char *prefix,
+                                       const char *name,
+                                       const char *val)
+{
+       char buf[MAX_ENV_NAME + 1];
+       char *new;
+       size_t len;
+
+       new = set_env_name(prefix, name, buf);
+       if (new) {
+               len = strlen(new);
+               list = macro_addvar(list, new, len, val);
+       }
+       return list;
+}
+
+static struct substvar *do_macro_removevar(struct substvar *list,
+                                          const char *prefix,
+                                          const char *name)
+{
+       char buf[MAX_ENV_NAME + 1];
+       char *new;
+       size_t len;
+
+       new = set_env_name(prefix, name, buf);
+       if (new) {
+               len = strlen(new);
+               list = macro_removevar(list, new, len);
+       }
+       return list;
+}
+
+struct substvar *addstdenv(struct substvar *sv, const char *prefix)
 {
        struct substvar *list = sv;
        struct thread_stdenv_vars *tsv;
@@ -331,14 +386,14 @@ struct substvar *addstdenv(struct substv
                num = (long) tsv->uid;
                ret = sprintf(numbuf, "%ld", num);
                if (ret > 0)
-                       list = macro_addvar(list, "UID", 3, numbuf);
+                       list = do_macro_addvar(list, prefix, "UID", numbuf);
                num = (long) tsv->gid;
                ret = sprintf(numbuf, "%ld", num);
                if (ret > 0)
-                       list = macro_addvar(list, "GID", 3, numbuf);
-               list = macro_addvar(list, "USER", 4, tsv->user);
-               list = macro_addvar(list, "GROUP", 5, tsv->group);
-               list = macro_addvar(list, "HOME", 4, tsv->home);
+                       list = do_macro_addvar(list, prefix, "GID", numbuf);
+               list = do_macro_addvar(list, prefix, "USER", tsv->user);
+               list = do_macro_addvar(list, prefix, "GROUP", tsv->group);
+               list = do_macro_addvar(list, prefix, "HOME", tsv->home);
                mv = macro_findvar(list, "HOST", 4);
                if (mv) {
                        char *shost = strdup(mv->val);
@@ -346,7 +401,8 @@ struct substvar *addstdenv(struct substv
                                char *dot = strchr(shost, '.');
                                if (dot)
                                        *dot = '\0';
-                               list = macro_addvar(list, "SHOST", 5, shost);
+                               list = do_macro_addvar(list,
+                                                      prefix, "SHOST", shost);
                                free(shost);
                        }
                }
@@ -354,16 +410,16 @@ struct substvar *addstdenv(struct substv
        return list;
 }
 
-struct substvar *removestdenv(struct substvar *sv)
+struct substvar *removestdenv(struct substvar *sv, const char *prefix)
 {
        struct substvar *list = sv;
 
-       list = macro_removevar(list, "UID", 3);
-       list = macro_removevar(list, "USER", 4);
-       list = macro_removevar(list, "HOME", 4);
-       list = macro_removevar(list, "GID", 3);
-       list = macro_removevar(list, "GROUP", 5);
-       list = macro_removevar(list, "SHOST", 5);
+       list = do_macro_removevar(list, prefix, "UID");
+       list = do_macro_removevar(list, prefix, "USER");
+       list = do_macro_removevar(list, prefix, "HOME");
+       list = do_macro_removevar(list, prefix, "GID");
+       list = do_macro_removevar(list, prefix, "GROUP");
+       list = do_macro_removevar(list, prefix, "SHOST");
        return list;
 }
 
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -181,7 +181,7 @@ static char *lookup_one(struct autofs_po
                if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) {
                        struct parse_context *pctxt = (struct parse_context *) 
ctxt->parse->context;
                        /* Add standard environment as seen by sun map parser */
-                       pctxt->subst = addstdenv(pctxt->subst);
+                       pctxt->subst = addstdenv(pctxt->subst, "AUTOFS_");
                        macro_setenv(pctxt->subst);
                }
                execl(ctxt->mapname, ctxt->mapname, name, NULL);
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1214,12 +1214,12 @@ int parse_mount(struct autofs_point *ap,
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
        macro_lock();
 
-       ctxt->subst = addstdenv(ctxt->subst);
+       ctxt->subst = addstdenv(ctxt->subst, NULL);
 
        mapent_len = expandsunent(mapent, NULL, name, ctxt->subst, slashify);
        if (mapent_len == 0) {
                error(ap->logopt, MODPREFIX "failed to expand map entry");
-               ctxt->subst = removestdenv(ctxt->subst);
+               ctxt->subst = removestdenv(ctxt->subst, NULL);
                macro_unlock();
                pthread_setcancelstate(cur_state, NULL);
                return 1;
@@ -1229,7 +1229,7 @@ int parse_mount(struct autofs_point *ap,
        if (!pmapent) { 
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
                logerr(MODPREFIX "alloca: %s", estr);
-               ctxt->subst = removestdenv(ctxt->subst);
+               ctxt->subst = removestdenv(ctxt->subst, NULL);
                macro_unlock();
                pthread_setcancelstate(cur_state, NULL);
                return 1;
@@ -1237,7 +1237,7 @@ int parse_mount(struct autofs_point *ap,
        pmapent[mapent_len] = '\0';
 
        expandsunent(mapent, pmapent, name, ctxt->subst, slashify);
-       ctxt->subst = removestdenv(ctxt->subst);
+       ctxt->subst = removestdenv(ctxt->subst, NULL);
 
        macro_unlock();
        pthread_setcancelstate(cur_state, NULL);
++++++ autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch 
++++++
autofs-5.1.0 - add config option to force use of program map stdvars

From: Ian Kent <ik...@redhat.com>

Enabling the extended environment (including $HOME, for example) for
program maps opens automount(8) to a privilege escalation.

Rather than just removing the entended environment a configuration
option is added to disable it by default so that those who wish to
use it can do so if they wish.
---
 include/defaults.h             |    2 ++
 lib/defaults.c                 |   12 ++++++++++++
 man/autofs.5                   |    5 +++++
 man/autofs.conf.5.in           |    9 +++++++++
 modules/lookup_program.c       |   14 +++++++++++++-
 redhat/autofs.conf.default.in  |   11 +++++++++++
 samples/autofs.conf.default.in |   11 +++++++++++
 7 files changed, 63 insertions(+), 1 deletion(-)

--- a/include/defaults.h
+++ b/include/defaults.h
@@ -30,6 +30,7 @@
 #define DEFAULT_UMOUNT_WAIT            "12"
 #define DEFAULT_BROWSE_MODE            "1"
 #define DEFAULT_LOGGING                        "none"
+#define DEFAULT_FORCE_STD_PROG_MAP_ENV "0"
 
 #define DEFAULT_LDAP_TIMEOUT           "-1"
 #define DEFAULT_LDAP_NETWORK_TIMEOUT   "8"
@@ -151,6 +152,7 @@ unsigned int defaults_get_timeout(void);
 unsigned int defaults_get_negative_timeout(void);
 unsigned int defaults_get_browse_mode(void);
 unsigned int defaults_get_logging(void);
+unsigned int defaults_force_std_prog_map_env(void);
 const char *defaults_get_ldap_server(void);
 unsigned int defaults_get_ldap_timeout(void);
 unsigned int defaults_get_ldap_network_timeout(void);
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -50,6 +50,7 @@
 #define NAME_NEGATIVE_TIMEOUT          "negative_timeout"
 #define NAME_BROWSE_MODE               "browse_mode"
 #define NAME_LOGGING                   "logging"
+#define NAME_FORCE_STD_PROG_MAP_ENV    "force_standard_program_map_env"
 
 #define NAME_LDAP_URI                  "ldap_uri"
 #define NAME_LDAP_TIMEOUT              "ldap_timeout"
@@ -1571,6 +1572,17 @@ unsigned int defaults_get_logging(void)
        return logging;
 }
 
+unsigned int defaults_force_std_prog_map_env(void)
+{
+       int res;
+
+       res = conf_get_yesno(autofs_gbl_sec, NAME_FORCE_STD_PROG_MAP_ENV);
+       if (res < 0)
+               res = atoi(DEFAULT_FORCE_STD_PROG_MAP_ENV);
+
+       return res;
+}
+
 unsigned int defaults_get_ldap_timeout(void)
 {
        int res;
--- a/man/autofs.5
+++ b/man/autofs.5
@@ -190,6 +190,11 @@ SHOST      Short hostname (domain part remove
 .fi
 .RE
 .sp
+If a program map is used these standard environment variables will have
+a prefix of "AUTOFS_" to prevent interpreted languages like python from
+being able to load and execute arbitray code from a user home directory.
+.RE
+.sp
 Additional entries can be defined with the -Dvariable=Value map-option to
 .BR automount (8).
 .SS Executable Maps
--- a/man/autofs.conf.5.in
+++ b/man/autofs.conf.5.in
@@ -71,6 +71,15 @@ options replace the global options (prog
 .B logging
 .br
 set default log level "none", "verbose" or "debug" (program default "none").
+.TP
+.B force_standard_program_map_env
+.br
+override the use of a prefix with standard environment variables when a
+program map is executed. Since program maps are run as the privileded
+user setting these standard environment variables opens automount(8) to
+potential user privilege escalation when the program map is written in a
+language that can load components from, for example, a user home directory
+(program default "no").
 .SS LDAP Configuration
 .P
 Configuration settings available are:
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -129,6 +129,7 @@ static char *lookup_one(struct autofs_po
        int distance;
        int alloci = 1;
        int status;
+       char *prefix;
 
        mapent = (char *) malloc(MAPENT_MAX_LEN + 1);
        if (!mapent) {
@@ -174,6 +175,17 @@ static char *lookup_one(struct autofs_po
                        warn(ap->logopt,
                             MODPREFIX "failed to set PWD to %s for map %s",
                             ap->path, ctxt->mapname);
+
+               /*
+                * By default use a prefix with standard environment
+                * variables to prevent system subversion by interpreted
+                * languages.
+                */
+               if (defaults_force_std_prog_map_env())
+                       prefix = NULL;
+               else
+                       prefix = "AUTOFS_";
+
                /*
                 * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup
                 * the macro table.
@@ -181,7 +193,7 @@ static char *lookup_one(struct autofs_po
                if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) {
                        struct parse_context *pctxt = (struct parse_context *) 
ctxt->parse->context;
                        /* Add standard environment as seen by sun map parser */
-                       pctxt->subst = addstdenv(pctxt->subst, "AUTOFS_");
+                       pctxt->subst = addstdenv(pctxt->subst, prefix);
                        macro_setenv(pctxt->subst);
                }
                execl(ctxt->mapname, ctxt->mapname, name, NULL);
--- a/redhat/autofs.conf.default.in
+++ b/redhat/autofs.conf.default.in
@@ -53,6 +53,17 @@ mount_nfs_default_protocol = 4
 #
 #logging = none
 #
+# force_standard_program_map_env - disable the use of the "AUTOFS_"
+#                      prefix for standard environemt variables when
+#                      executing a program map. Since program maps
+#                      are run as the privileded user this opens
+#                      automount(8) to potential user privilege
+#                      escalation when the program map is written
+#                      in a language that  can load components from,
+#                      for example, a user home directory.
+#
+# force_standard_program_map_env = no
+#
 # Define base dn for map dn lookup.
 #
 # Define server URIs
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -52,6 +52,17 @@ browse_mode = no
 #
 #logging = none
 #
+# force_standard_program_map_env - disable the use of the "AUTOFS_"
+#                      prefix for standard environemt variables when
+#                      executing a program map. Since program maps
+#                      are run as the privileded user this opens
+#                      automount(8) to potential user privilege
+#                      escalation when the program map is written
+#                      in a language that  can load components from,
+#                      for example, a user home directory.
+#
+# force_standard_program_map_env = no
+#
 # Define base dn for map dn lookup.
 #
 # Define server URIs

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to