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

Bug#426465: init should clear environment



severity 505440 critical
# justification: is the cause of 426465, which is critical
clone 505440 -1
reassign -1 sysvinit
retitle -1 init should clear environment
tag -1 patch
thanks

For background, see #426465 and #505440, which is a more general
description of #426465.

initramfs exports an environment in /init with variables that confuse
some initscripts.  Ubuntu has fixed this by having upstart clear its
environment.  It looks like initramfs-tools should be fixed by having
it export a smaller environment, but we can and probably should also
fix the problems it causes by having init clear its environment in
child processes.

The attached patch does this.

upstart passes on two environment variables, PATH and TERM, so this
patch does the same.

Applying this change breaks an old-fashioned practice in initscripts
of getting certain variables from the kernel command line by expecting
them to be exported in the environment. An Ubuntu bug from 2006
(https://bugs.launchpad.net/bugs/74664) describes a situation where
this cropped up when they implemented the change.  The correct way for
an initscript to do this is to look in /proc/cmdline, as e.g. the
initscripts package does in /etc/init.d/stop-bootlogd-single.  It's
possible that some packages still use the old-fashioned practice.

Once this patch or another fix is uploaded, bugs #426465 and #505440
in initramfs-tools can be downgraded.

Greg
#! /bin/sh /usr/share/dpatch/dpatch-run
## 95_clear_environment.dpatch by Greg Price

Clear the environment when spawning a process.

@DPATCH@


diff -urNad trunk~/src/init.c trunk/src/init.c
--- trunk~/src/init.c	2008-12-13 20:35:24.000000000 -0500
+++ trunk/src/init.c	2008-12-13 20:35:24.000000000 -0500
@@ -188,6 +188,8 @@ struct {
 	{NULL,0}
 };
 
+char * const default_env_vars[] = {"PATH", "TERM", NULL};
+
 #define NR_EXTRA_ENV	16
 char *extra_env[NR_EXTRA_ENV];
 
@@ -782,13 +784,27 @@ char **init_buildenv(int child)
 	char		**e;
 	int		n, i;
 
-	for (n = 0; environ[n]; n++)
-		;
+	if (child) {
+		for (n = 0; default_env_vars[n]; n++)
+			;
+	} else {
+		for (n = 0; environ[n]; n++)
+			;
+	}
 	n += NR_EXTRA_ENV + 8;
 	e = calloc(n, sizeof(char *));
 
-	for (n = 0; environ[n]; n++)
-		e[n] = istrdup(environ[n]);
+	if (child) {
+		for (n = 0; default_env_vars[n]; n++) {
+			char *key = default_env_vars[n];
+			char *value = getenv(key);
+			e[n] = imalloc(strlen(key) + strlen(value) + 2);
+			sprintf(e[n], "%s=%s", key, value);
+		}
+	} else {
+		for (n = 0; environ[n]; n++)
+			e[n] = istrdup(environ[n]);
+	}
 
 	for (i = 0; i < NR_EXTRA_ENV; i++)
 		if (extra_env[i])

Reply to: