Environment handling broken in /bin/sh with changes to {get,set,put}env()

Andrey Chernov ache at nagual.pp.ru
Wed Jul 4 15:03:16 UTC 2007


On Wed, Jul 04, 2007 at 06:36:42PM +0400, Andrey Chernov wrote:
> 2) "s" may point to getenv()-provided value there. So just modifying it 
> directly followed by setenv() call will make things inconsistent.
> 
> 3) In my version of patch there was savestr() which copy arg to avoid this 
> situation.
> 
> Fix will be to restore var.c to mine variant 1.34

You may also try this patch against var.c 1.36:

Index: var.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/var.c,v
retrieving revision 1.36
diff -u -r1.36 var.c
--- var.c	4 Jul 2007 00:00:38 -0000	1.36
+++ var.c	4 Jul 2007 14:59:19 -0000
@@ -289,7 +289,7 @@
 setvareq(char *s, int flags)
 {
 	struct var *vp, **vpp;
-	char *p;
+	char *p, *ss;
 	int len;
 
 	if (aflag)
@@ -320,10 +320,11 @@
 			if (vp == &vmpath || (vp == &vmail && ! mpathset()))
 				chkmail(1);
 			if ((vp->flags & VEXPORT) && localevar(s)) {
-				p = strchr(s, '=');
+				ss = savestr(s);
+				p = strchr(ss, '=');
 				*p = '\0';
-				(void) setenv(s, p + 1, 1);
-				*p = '=';
+				(void) setenv(ss, p + 1, 1);
+				ckfree(ss);
 				(void) setlocale(LC_ALL, "");
 			}
 			INTON;
@@ -339,10 +340,11 @@
 	INTOFF;
 	*vpp = vp;
 	if ((vp->flags & VEXPORT) && localevar(s)) {
-		p = strchr(s, '=');
+		ss = savestr(s);
+		p = strchr(ss, '=');
 		*p = '\0';
-		(void) setenv(s, p + 1, 1);
-		*p = '=';
+		(void) setenv(ss, p + 1, 1);
+		ckfree(ss);
 		(void) setlocale(LC_ALL, "");
 	}
 	INTON;
@@ -567,7 +569,7 @@
 	struct var **vpp;
 	struct var *vp;
 	char *name;
-	char *p;
+	char *p, *ss;
 	char *cmdname;
 	int ch, values;
 	int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
@@ -603,10 +605,11 @@
 
 						vp->flags |= flag;
 						if ((vp->flags & VEXPORT) && localevar(vp->text)) {
-							p = strchr(vp->text, '=');
+							ss = savestr(vp->text);
+							p = strchr(ss, '=');
 							*p = '\0';
-							(void) setenv(vp->text, p + 1, 1);
-							*p = '=';
+							(void) setenv(ss, p + 1, 1);
+							ckfree(ss);
 							(void) setlocale(LC_ALL, "");
 						}
 						goto found;
@@ -788,6 +791,7 @@
 {
 	struct var **vpp;
 	struct var *vp;
+	char *ss, *eqp;
 
 	vpp = hashvar(s);
 	for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
@@ -798,7 +802,11 @@
 			if (*(strchr(vp->text, '=') + 1) != '\0')
 				setvar(s, nullstr, 0);
 			if ((vp->flags & VEXPORT) && localevar(vp->text)) {
-				unsetenv(s);
+				ss = savestr(s);
+				if ((eqp = strchr(ss, '=')) != NULL)
+					*eqp = '\0';
+				(void) unsetenv(ss);
+				ckfree(ss);
 				setlocale(LC_ALL, "");
 			}
 			vp->flags &= ~VEXPORT;

-- 
http://ache.pp.ru/


More information about the freebsd-current mailing list