Your message dated Thu, 19 Mar 2015 09:19:21 +0000
with message-id <[email protected]>
and subject line Bug#779591: fixed in autofs 5.0.8-2
has caused the Debian Bug report #779591,
regarding autofs: CVE-2014-8169: privilege escalation via interpreter load path 
for program based automount maps
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
779591: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779591
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Source: autofs
Version: 5.0.8-1
Severity: important
Tags: security upstream patch

Hi,

the following vulnerability was published for autofs.

CVE-2014-8169[0]:
priv escalation via interpreter load path for program based automount maps

If you fix the vulnerability please also make sure to include the
CVE (Common Vulnerabilities & Exposures) id in your changelog entry.

For further information see:

[0] https://security-tracker.debian.org/tracker/CVE-2014-8169
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1192565

Attached are the backported patches for 5.0.8, lightly tested but a
second pair of eyes to review would be welcome.

Regards,
Salvatore
diff -Nru autofs-5.0.8/debian/changelog autofs-5.0.8/debian/changelog
--- autofs-5.0.8/debian/changelog	2014-03-07 05:16:25.000000000 +0100
+++ autofs-5.0.8/debian/changelog	2015-02-28 23:11:25.000000000 +0100
@@ -1,3 +1,21 @@
+autofs (5.0.8-1.1) unstable; urgency=high
+
+  * Non-maintainer upload by the Security Team.
+  * Add patches for CVE-2014-8169.
+    When a program map uses an interpreted languages like python it is
+    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.
+    Additionally a configuration option to force the use of program map
+    standard environment variables is added
+    (FORCE_STANDARD_PROGRAM_MAP_ENV).
+  * Refresh remove-kernel-mount.nfs-version-check.patch patch
+  * Refresh manpages-hyphen.patch patch
+
+ -- Salvatore Bonaccorso <[email protected]>  Sat, 28 Feb 2015 20:23:20 +0100
+
 autofs (5.0.8-1) unstable; urgency=low
 
   * New upstream release [October 2013] (Closes: #729023).
diff -Nru autofs-5.0.8/debian/patches/CVE-2014-8169-add-a-prefix-to-program-map-stdvars.patch autofs-5.0.8/debian/patches/CVE-2014-8169-add-a-prefix-to-program-map-stdvars.patch
--- autofs-5.0.8/debian/patches/CVE-2014-8169-add-a-prefix-to-program-map-stdvars.patch	1970-01-01 01:00:00.000000000 +0100
+++ autofs-5.0.8/debian/patches/CVE-2014-8169-add-a-prefix-to-program-map-stdvars.patch	2015-02-28 23:11:25.000000000 +0100
@@ -0,0 +1,200 @@
+Description: add a prefix to program map stdvars
+ When a program map uses an interpreted languages like python it is
+ possible to load and execute arbitrary code from a user home directory.
+ This is because the standard environment variables are used to locate
+ and load modules when using these languages. (CVE-2014-8169)
+ .
+ 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.
+Origin: vendor
+Author: Ian Kent <[email protected]>
+Reviewed-by: Salvatore Bonaccorso <[email protected]>
+Last-Update: 2015-02-28
+---
+--- a/include/mounts.h
++++ b/include/mounts.h
+@@ -85,8 +85,8 @@ unsigned int linux_version_code(void);
+ int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
+ extern unsigned int nfs_mount_uses_string_options;
+ 
+-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);
+ 
+ unsigned int query_kproto_ver(void);
+ unsigned int get_kver_major(void);
+--- a/lib/mounts.c
++++ b/lib/mounts.c
+@@ -31,6 +31,7 @@
+ 
+ #define MAX_OPTIONS_LEN		80
+ #define MAX_MNT_NAME_LEN	30
++#define MAX_ENV_NAME		15
+ 
+ #define EBUFSIZ 1024
+ 
+@@ -303,7 +304,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;
+@@ -318,14 +373,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);
+@@ -333,7 +388,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);
+ 			}
+ 		}
+@@ -341,16 +397,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
+@@ -272,7 +272,7 @@ int lookup_mount(struct autofs_point *ap
+ 		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
+@@ -1223,12 +1223,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;
+@@ -1238,7 +1238,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;
+@@ -1246,7 +1246,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);
diff -Nru autofs-5.0.8/debian/patches/CVE-2014-8169-add-config-option-to-force-use-of-program-map-stdvars.patch autofs-5.0.8/debian/patches/CVE-2014-8169-add-config-option-to-force-use-of-program-map-stdvars.patch
--- autofs-5.0.8/debian/patches/CVE-2014-8169-add-config-option-to-force-use-of-program-map-stdvars.patch	1970-01-01 01:00:00.000000000 +0100
+++ autofs-5.0.8/debian/patches/CVE-2014-8169-add-config-option-to-force-use-of-program-map-stdvars.patch	2015-02-28 23:11:25.000000000 +0100
@@ -0,0 +1,137 @@
+Description:  add config option to force use of program map stdvars
+ 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.
+Origin: vendor
+Author: Ian Kent <[email protected]>
+Author: Salvatore Bonaccorso <[email protected]>
+Last-Update: 2015-02-28
+---
+--- a/include/defaults.h
++++ b/include/defaults.h
+@@ -28,6 +28,7 @@
+ #define DEFAULT_UMOUNT_WAIT		12
+ #define DEFAULT_BROWSE_MODE		1
+ #define DEFAULT_LOGGING			0
++#define DEFAULT_FORCE_STD_PROG_MAP_ENV  0
+ 
+ #define DEFAULT_LDAP_TIMEOUT		-1
+ #define DEFAULT_LDAP_NETWORK_TIMEOUT	8
+@@ -62,6 +63,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
+@@ -35,6 +35,7 @@
+ #define ENV_NAME_NEGATIVE_TIMEOUT	"NEGATIVE_TIMEOUT"
+ #define ENV_NAME_BROWSE_MODE		"BROWSE_MODE"
+ #define ENV_NAME_LOGGING		"LOGGING"
++#define ENV_NAME_FORCE_STD_PROG_MAP_ENV "FORCE_STANDARD_PROGRAM_MAP_ENV"
+ 
+ #define LDAP_URI			"LDAP_URI"
+ #define ENV_LDAP_TIMEOUT		"LDAP_TIMEOUT"
+@@ -519,6 +520,7 @@ unsigned int defaults_read_config(unsign
+ 		    check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) ||
+ 		    check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) ||
+ 		    check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) ||
++		    check_set_config_value(key, ENV_NAME_FORCE_STD_PROG_MAP_ENV, value, to_syslog) ||
+ 		    check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) ||
+ 		    check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) ||
+ 		    check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) ||
+@@ -629,6 +631,17 @@ unsigned int defaults_get_logging(void)
+ 	return logging;
+ }
+ 
++unsigned int defaults_force_std_prog_map_env(void)
++{
++	int res;
++
++	res = get_env_yesno(ENV_NAME_FORCE_STD_PROG_MAP_ENV);
++	if (res < 0)
++		res = 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
+@@ -174,6 +174,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/modules/lookup_program.c
++++ b/modules/lookup_program.c
+@@ -132,6 +132,7 @@ int lookup_mount(struct autofs_point *ap
+ 	int ret = 1;
+ 	int distance;
+ 	int alloci = 1;
++	char *prefix;
+ 
+ 	source = ap->entry->current;
+ 	ap->entry->current = NULL;
+@@ -265,6 +266,17 @@ int lookup_mount(struct autofs_point *ap
+ 			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.
+@@ -272,7 +284,7 @@ int lookup_mount(struct autofs_point *ap
+ 		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/samples/autofs.conf.default.in
++++ b/samples/autofs.conf.default.in
+@@ -80,6 +80,17 @@ BROWSE_MODE="no"
+ #
+ #LDAP_NETWORK_TIMEOUT=8
+ #
++# FORCE_STANDARD_PROGRAM_MAP_ENV - disable the use of the "AUTOFS_"
++#			prefix for standard environment 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.
+ #
+ # SEARCH_BASE - base dn to use for searching for map search dn.
diff -Nru autofs-5.0.8/debian/patches/manpages-hyphen.patch autofs-5.0.8/debian/patches/manpages-hyphen.patch
--- autofs-5.0.8/debian/patches/manpages-hyphen.patch	2014-03-07 05:16:07.000000000 +0100
+++ autofs-5.0.8/debian/patches/manpages-hyphen.patch	2015-02-28 23:11:25.000000000 +0100
@@ -5,8 +5,7 @@
 
 --- a/man/autofs.5
 +++ b/man/autofs.5
-@@ -21,9 +21,9 @@
- This is a description of the text file format.  Other methods of specifying
+@@ -22,7 +22,7 @@ This is a description of the text file f
  these files may exist.  All empty lines or lines beginning with # are
  ignored. The basic format of one line in such maps is:
  .P
@@ -15,9 +14,7 @@
  
  .SS key
  For indirect mounts this is the part of the path name between the mount point
- and the path into the filesystem when it is mounted. Usually you can think about the
-@@ -39,22 +39,22 @@
- from SunOS).  The options are a list of comma separated options as
+@@ -40,20 +40,20 @@ from SunOS).  The options are a list of
  customary for the
  .BR mount (8)
  command. There are two special options
@@ -42,9 +39,7 @@
  can be used to negate the option if it is present in the master map entry
  for the map but is not wanted for the given mount.
  
- .SS location
-@@ -71,15 +71,15 @@
- .sp
+@@ -72,13 +72,13 @@ Indirect map:
  .RS +.2i
  .ta 1.0i 3.0i
  .nf
@@ -65,9 +60,7 @@
  			/usr myserver.me.org:/usr \\
  			/home myserver.me.org:/home
  .fi
- .RE
-@@ -103,9 +103,9 @@
- .sp
+@@ -104,7 +104,7 @@ example entry for an autofs map:
  .RS +.2i
  .ta 1.0i 3.0i
  .nf
@@ -76,9 +69,7 @@
  .fi
  .RE
  .sp
- Direct map:
-@@ -149,14 +149,14 @@
- .sp
+@@ -150,12 +150,12 @@ scripts (Curly braces can be used to sep
  .RS +.2i
  .ta 1.5i
  .nf
@@ -96,10 +87,8 @@
  .fi
  .RE
  .sp
- autofs provides additional variables that are set based on the
-@@ -173,9 +173,9 @@
- SHOST	Short hostname (domain part removed if present)
- .fi
+@@ -179,7 +179,7 @@ a prefix of "AUTOFS_" to prevent interpr
+ 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
@@ -107,11 +96,9 @@
  .BR automount (8).
  .SS Executable Maps
  A map can be marked as executable. A
- .B program
 --- a/man/auto.master.5.in
 +++ b/man/auto.master.5.in
-@@ -249,19 +249,19 @@
- options replace the global options (program default "yes", append options).
+@@ -250,8 +250,8 @@ options replace the global options (prog
  .TP
  .B LOGGING
  set default log level "none", "verbose" or "debug" (program default "none").
@@ -122,8 +109,7 @@
  which corresponds to a hostname will allow access to the exports of that
  host. The hosts map cannot be dynamically updated and requires a HUP signal
  to be sent to the daemon for it to check hosts for an update. Due to possible
- hierarchic dependencies within a mount tree, it might not be completely
- updated during the HUP signal processing.
+@@ -260,7 +260,7 @@ updated during the HUP signal processing
  .P
  For example, with an entry in the master map of
  .nh
@@ -132,4 +118,3 @@
  .hy
  accessing /net/myserver will mount exports from myserver on directories below
  /net/myserver.
- .P
diff -Nru autofs-5.0.8/debian/patches/remove-kernel-mount.nfs-version-check.patch autofs-5.0.8/debian/patches/remove-kernel-mount.nfs-version-check.patch
--- autofs-5.0.8/debian/patches/remove-kernel-mount.nfs-version-check.patch	2014-03-07 05:16:07.000000000 +0100
+++ autofs-5.0.8/debian/patches/remove-kernel-mount.nfs-version-check.patch	2015-02-28 23:11:25.000000000 +0100
@@ -22,8 +22,7 @@
 
 --- a/daemon/automount.c
 +++ b/daemon/automount.c
-@@ -50,11 +50,8 @@
- const char *libdir = AUTOFS_LIB_DIR;	/* Location of library modules */
+@@ -51,9 +51,6 @@ const char *libdir = AUTOFS_LIB_DIR;	/*
  const char *mapdir = AUTOFS_MAP_DIR;	/* Location of mount maps */
  const char *confdir = AUTOFS_CONF_DIR;	/* Location of autofs config file */
  
@@ -33,9 +32,7 @@
  /* autofs fifo name prefix */
  const char *fifodir = AUTOFS_FIFO_DIR "/autofs.fifo";
  
- const char *global_options;		/* Global option, from command line */
-@@ -1284,10 +1281,8 @@
- 	status = pthread_mutex_lock(&mrc.mutex);
+@@ -1285,8 +1282,6 @@ static int do_hup_signal(struct master *
  	if (status)
  		fatal(status);
  
@@ -44,9 +41,7 @@
  	master_mutex_lock();
  	/* Already doing a map read or shutdown or no mounts */
  	if (master->reading) {
- 		status = pthread_mutex_unlock(&mrc.mutex);
-@@ -1951,10 +1946,8 @@
- 	program = argv[0];
+@@ -1952,8 +1947,6 @@ int main(int argc, char *argv[])
  
  	defaults_read_config(0);
  
@@ -55,11 +50,9 @@
  	kpkt_len = get_kpkt_len();
  	timeout = defaults_get_timeout();
  	ghost = defaults_get_browse_mode();
- 	logging = defaults_get_logging();
 --- a/include/mounts.h
 +++ b/include/mounts.h
-@@ -75,16 +75,9 @@
- 	struct list_head ordered;
+@@ -76,14 +76,7 @@ struct mnt_list {
  };
  
  
@@ -72,13 +65,11 @@
 -int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
 -extern unsigned int nfs_mount_uses_string_options;
  
- 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);
 --- a/modules/replicated.c
 +++ b/modules/replicated.c
-@@ -885,11 +885,10 @@
- 	 * greater than 2.6.22 and mount.nfs version is greater than 1.1.1.
+@@ -886,9 +886,8 @@ int prune_host_list(unsigned logopt, str
  	 * But also allow the MOUNT_WAIT configuration parameter to override
  	 * the probing.
  	 */
@@ -90,11 +81,9 @@
  		if (!this)
  			return 1;
  	} else {
- 		if (!this || !this->next)
 --- a/lib/mounts.c
 +++ b/lib/mounts.c
-@@ -163,8 +163,9 @@
- {
+@@ -165,6 +165,7 @@ unsigned int get_kver_minor(void)
  	return kver.minor;
  }
  
@@ -102,14 +91,11 @@
  #ifdef HAVE_MOUNT_NFS
  static int extract_version(char *start, struct nfs_mount_vers *vers)
  {
- 	char *s_ver = strchr(start, ' ');
-@@ -301,8 +302,9 @@
- {
+@@ -303,6 +304,7 @@ int check_nfs_mount_version(struct nfs_m
  	return 0;
  }
  #endif
 +#endif
  
- struct substvar *addstdenv(struct substvar *sv)
+ static char *set_env_name(const char *prefix, const char *name, char *buf)
  {
- 	struct substvar *list = sv;
diff -Nru autofs-5.0.8/debian/patches/series autofs-5.0.8/debian/patches/series
--- autofs-5.0.8/debian/patches/series	2014-03-07 05:16:07.000000000 +0100
+++ autofs-5.0.8/debian/patches/series	2015-02-28 23:11:25.000000000 +0100
@@ -1,4 +1,8 @@
 #
+# CVE-2014-8169
+CVE-2014-8169-add-a-prefix-to-program-map-stdvars.patch
+CVE-2014-8169-add-config-option-to-force-use-of-program-map-stdvars.patch
+#
 # bugfixes forwarded to upstream
 filagdir.patch
 #
@@ -15,3 +19,4 @@
 link-daemon-with-lpthread.patch
 fix-ldflags.patch
 remove-kernel-mount.nfs-version-check.patch
+
Description: add a prefix to program map stdvars
 When a program map uses an interpreted languages like python it is
 possible to load and execute arbitrary code from a user home directory.
 This is because the standard environment variables are used to locate
 and load modules when using these languages. (CVE-2014-8169)
 .
 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.
Origin: vendor
Author: Ian Kent <[email protected]>
Reviewed-by: Salvatore Bonaccorso <[email protected]>
Last-Update: 2015-02-28
---
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -85,8 +85,8 @@ unsigned int linux_version_code(void);
 int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
 extern unsigned int nfs_mount_uses_string_options;
 
-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);
 
 unsigned int query_kproto_ver(void);
 unsigned int get_kver_major(void);
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -31,6 +31,7 @@
 
 #define MAX_OPTIONS_LEN		80
 #define MAX_MNT_NAME_LEN	30
+#define MAX_ENV_NAME		15
 
 #define EBUFSIZ 1024
 
@@ -303,7 +304,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;
@@ -318,14 +373,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);
@@ -333,7 +388,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);
 			}
 		}
@@ -341,16 +397,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
@@ -272,7 +272,7 @@ int lookup_mount(struct autofs_point *ap
 		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
@@ -1223,12 +1223,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;
@@ -1238,7 +1238,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;
@@ -1246,7 +1246,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);
Description:  add config option to force use of program map stdvars
 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.
Origin: vendor
Author: Ian Kent <[email protected]>
Author: Salvatore Bonaccorso <[email protected]>
Last-Update: 2015-02-28
---
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -28,6 +28,7 @@
 #define DEFAULT_UMOUNT_WAIT		12
 #define DEFAULT_BROWSE_MODE		1
 #define DEFAULT_LOGGING			0
+#define DEFAULT_FORCE_STD_PROG_MAP_ENV  0
 
 #define DEFAULT_LDAP_TIMEOUT		-1
 #define DEFAULT_LDAP_NETWORK_TIMEOUT	8
@@ -62,6 +63,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
@@ -35,6 +35,7 @@
 #define ENV_NAME_NEGATIVE_TIMEOUT	"NEGATIVE_TIMEOUT"
 #define ENV_NAME_BROWSE_MODE		"BROWSE_MODE"
 #define ENV_NAME_LOGGING		"LOGGING"
+#define ENV_NAME_FORCE_STD_PROG_MAP_ENV "FORCE_STANDARD_PROGRAM_MAP_ENV"
 
 #define LDAP_URI			"LDAP_URI"
 #define ENV_LDAP_TIMEOUT		"LDAP_TIMEOUT"
@@ -519,6 +520,7 @@ unsigned int defaults_read_config(unsign
 		    check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) ||
+		    check_set_config_value(key, ENV_NAME_FORCE_STD_PROG_MAP_ENV, value, to_syslog) ||
 		    check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) ||
@@ -629,6 +631,17 @@ unsigned int defaults_get_logging(void)
 	return logging;
 }
 
+unsigned int defaults_force_std_prog_map_env(void)
+{
+	int res;
+
+	res = get_env_yesno(ENV_NAME_FORCE_STD_PROG_MAP_ENV);
+	if (res < 0)
+		res = 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
@@ -174,6 +174,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/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -132,6 +132,7 @@ int lookup_mount(struct autofs_point *ap
 	int ret = 1;
 	int distance;
 	int alloci = 1;
+	char *prefix;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -265,6 +266,17 @@ int lookup_mount(struct autofs_point *ap
 			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.
@@ -272,7 +284,7 @@ int lookup_mount(struct autofs_point *ap
 		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/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -80,6 +80,17 @@ BROWSE_MODE="no"
 #
 #LDAP_NETWORK_TIMEOUT=8
 #
+# FORCE_STANDARD_PROGRAM_MAP_ENV - disable the use of the "AUTOFS_"
+#			prefix for standard environment 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.
 #
 # SEARCH_BASE - base dn to use for searching for map search dn.

--- End Message ---
--- Begin Message ---
Source: autofs
Source-Version: 5.0.8-2

We believe that the bug you reported is fixed in the latest version of
autofs, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [email protected],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Dmitry Smirnov <[email protected]> (supplier of updated autofs package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [email protected])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Thu, 19 Mar 2015 18:38:23 +1100
Source: autofs
Binary: autofs autofs-ldap autofs-hesiod autofs5 autofs5-ldap autofs5-hesiod
Architecture: source amd64 all
Version: 5.0.8-2
Distribution: unstable
Urgency: medium
Maintainer: Michael Tokarev <[email protected]>
Changed-By: Dmitry Smirnov <[email protected]>
Description:
 autofs     - kernel-based automounter for Linux
 autofs-hesiod - Hesiod map support for autofs
 autofs-ldap - LDAP map support for autofs
 autofs5    - transitional dummy package for 'autofs'
 autofs5-hesiod - transitional dummy package for 'autofs-hesiod'
 autofs5-ldap - transitional dummy package for 'autofs-ldap'
Closes: 779591
Changes:
 autofs (5.0.8-2) unstable; urgency=medium
 .
   [ Salvatore Bonaccorso <[email protected]> ]
   * Add patches for CVE-2014-8169 (Closes: #779591).
     When a program map uses an interpreted languages like python it is
     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, a prefix to
     these environment names is added so that they aren't used for this
     purpose. The prefix used is "AUTOFS_" and is not configurable.
     Additionally a configuration option to force the use of program map
     standard environment variables is added (FORCE_STANDARD_PROGRAM_MAP_ENV).
 .
   [ Dmitry Smirnov <[email protected]> ]
   * Refreshed other patches as needed.
Checksums-Sha1:
 d50642a1951f7ab4a017058ebd173ced462805c5 2344 autofs_5.0.8-2.dsc
 3dbd50793c2c6ec4aa20429a7eba3840f70ea630 20056 autofs_5.0.8-2.debian.tar.xz
 d6130191367fc387a2eff5fefe682b92bb996a09 317150 autofs_5.0.8-2_amd64.deb
 f60a1aa720a1b068e3013cfd7ccd6a0ac0cd4b83 91156 autofs-ldap_5.0.8-2_amd64.deb
 fc4fc204c517c28a8ea156b78124154805cb64fa 73234 autofs-hesiod_5.0.8-2_amd64.deb
 6d4258a23f25f245cd1de7efccfcd831a55ef80c 24238 autofs5_5.0.8-2_all.deb
 eaeec7eebb5b59caadc39c426089ea39108e79d3 24252 autofs5-ldap_5.0.8-2_all.deb
 ecd0ffcda3c0379f8bd370ce43f8e88490050409 24266 autofs5-hesiod_5.0.8-2_all.deb
Checksums-Sha256:
 99b071544fa3f8e2f9b2b16bdb9c7784eb2be01d6745d1e0ab487e26e38817df 2344 
autofs_5.0.8-2.dsc
 36690a9a6727b6a115ea866d17cee6c74b357763b33c3e3a46c3d1650da3a7a6 20056 
autofs_5.0.8-2.debian.tar.xz
 d5dfe3f6a99063ecab66c1849b97140fa1bae10420dd51f47053f617eba23c09 317150 
autofs_5.0.8-2_amd64.deb
 f7ed4cd5e9903fc6346386aa24033b76b30bddecb16899c6e376427e0c26b58f 91156 
autofs-ldap_5.0.8-2_amd64.deb
 11166f1521fce77af2169c3274dd5f91c426fcc7433d613c610ecb8b47d46ea6 73234 
autofs-hesiod_5.0.8-2_amd64.deb
 e27fe744c636808c0cf932dea2b7d671d72d55b96475622031acf263c4b5ed2e 24238 
autofs5_5.0.8-2_all.deb
 53d58dbdc90d9edbe50890dcdec106ed094de264ccb4b05d4c1427d6e12656b2 24252 
autofs5-ldap_5.0.8-2_all.deb
 56504aa36c1a7297232b6fa4a11e3bd708acb1641d914ed14ed7e13b3c90af85 24266 
autofs5-hesiod_5.0.8-2_all.deb
Files:
 13ea38db0ab27ab3a612ecd9bddc9d40 2344 utils extra autofs_5.0.8-2.dsc
 6fc256838c434bc361f50181119cc933 20056 utils extra autofs_5.0.8-2.debian.tar.xz
 8c583096285585d58040e28c4a2fe03e 317150 utils extra autofs_5.0.8-2_amd64.deb
 ff805c3d8f426bca37417dc2797ab279 91156 utils extra 
autofs-ldap_5.0.8-2_amd64.deb
 cff74ecde911d4f635d6d2eb541a1d67 73234 utils extra 
autofs-hesiod_5.0.8-2_amd64.deb
 cebd4fa1fba91e703987d6f657ac6f20 24238 oldlibs extra autofs5_5.0.8-2_all.deb
 23ff1ed10dc71f18d18568ebf79b4c65 24252 oldlibs extra 
autofs5-ldap_5.0.8-2_all.deb
 dd9fe8d3fc11e5d93bcf1df7fc446b99 24266 oldlibs extra 
autofs5-hesiod_5.0.8-2_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJVCoWeAAoJEFK2u9lTlo0b79UP/2UcgN33dZPhe/DWDnw/GDVG
0fc8zDDxChVItr4LyqdmztU5VMxwUPMV4NaPJXDXp+MDv4rel0BO22zSzymUL+B7
AloIZoaPsaOnqiBflOXNDrmiC4DecLTIuvSvUpIcaPgHG/vqsCvUu9kuYQrZt9VK
y+838sjbXlJBcGR4AWvTz0zb4XvggSagQKsnNgyIazKB3D1SRIkKzBMZAiixLSDb
CgDM0kSAjJM0aI+oWxHQFNlzyAi5MO2JpEQ+D4yQ94MT1z2RSO0uLwK71J2V3tiU
mANvvaDBH7rgD3SDD6g5b2MAmgIIAl42P+TvSJAJDVAhkHU+0TPOwYZR6wvM969P
TAmwgGN01V3FKkxomJVaZMEShaDG3dehoJ4ZujvCWjXammkxMwju4dXNw2BpvPjC
nZCkmI4jh4pmVUqW05cKhhWKIO2NeALKBSevW2/taGFhCcGbKYs4kTAV0GkQm/zP
gISr9hzY7IEhO0K77TcCkQs7Q1b583v3OzzshAKl3w/UFcljj5ot15zD/MtK7oRo
Fv5GFK2SLu/MZpb3VhG0mBDMenakCqDzOAC1Xy4V6B8UO/PptDU0T2ePkOc6pRIZ
H6ADgkURlbXdPKTX+B7UqtnSKW0ZDmfuq5CzyUev/LMSFJAZcDyxuUrRUxSuZjoU
IYkyyDEoHAK/dZIjloDP
=3uY/
-----END PGP SIGNATURE-----

--- End Message ---

Reply via email to