summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2010-08-23 22:31:50 +0000
committermillert <>2010-08-23 22:31:50 +0000
commit7242e103c3ca65b3f003c382301a3d65fe40846e (patch)
tree56ce07a012b5a620934d84e0ff9d7fb119096762
parentb3f615278798dc6689163d9c4243572a0011a133 (diff)
downloadopenbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.tar.gz
openbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.tar.bz2
openbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.zip
Check for duplicate variables in the environment when setting a value
via setenv() or putenv(). OK miod@
-rw-r--r--src/lib/libc/stdlib/getenv.c9
-rw-r--r--src/lib/libc/stdlib/setenv.c26
2 files changed, 24 insertions, 11 deletions
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c
index 5aff11c61a..fd8482e9e3 100644
--- a/src/lib/libc/stdlib/getenv.c
+++ b/src/lib/libc/stdlib/getenv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getenv.c,v 1.9 2009/06/03 15:52:16 millert Exp $ */ 1/* $OpenBSD: getenv.c,v 1.10 2010/08/23 22:31:50 millert Exp $ */
2/* 2/*
3 * Copyright (c) 1987, 1993 3 * Copyright (c) 1987, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -36,8 +36,9 @@ char *__findenv(const char *name, int len, int *offset);
36/* 36/*
37 * __findenv -- 37 * __findenv --
38 * Returns pointer to value associated with name, if any, else NULL. 38 * Returns pointer to value associated with name, if any, else NULL.
39 * Starts searching within the environmental array at offset.
39 * Sets offset to be the offset of the name/value combination in the 40 * Sets offset to be the offset of the name/value combination in the
40 * environmental array, for use by setenv(3) and unsetenv(3). 41 * environmental array, for use by putenv(3), setenv(3) and unsetenv(3).
41 * Explicitly removes '=' in argument name. 42 * Explicitly removes '=' in argument name.
42 * 43 *
43 * This routine *should* be a static; don't use it. 44 * This routine *should* be a static; don't use it.
@@ -52,7 +53,7 @@ __findenv(const char *name, int len, int *offset)
52 53
53 if (name == NULL || environ == NULL) 54 if (name == NULL || environ == NULL)
54 return (NULL); 55 return (NULL);
55 for (p = environ; (cp = *p) != NULL; ++p) { 56 for (p = environ + *offset; (cp = *p) != NULL; ++p) {
56 for (np = name, i = len; i && *cp; i--) 57 for (np = name, i = len; i && *cp; i--)
57 if (*cp++ != *np++) 58 if (*cp++ != *np++)
58 break; 59 break;
@@ -71,7 +72,7 @@ __findenv(const char *name, int len, int *offset)
71char * 72char *
72getenv(const char *name) 73getenv(const char *name)
73{ 74{
74 int offset; 75 int offset = 0;
75 const char *np; 76 const char *np;
76 77
77 for (np = name; *np && *np != '='; ++np) 78 for (np = name; *np && *np != '='; ++np)
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c
index 89d1e88911..089ab92d38 100644
--- a/src/lib/libc/stdlib/setenv.c
+++ b/src/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: setenv.c,v 1.12 2010/06/29 04:09:34 naddy Exp $ */ 1/* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */
2/* 2/*
3 * Copyright (c) 1987 Regents of the University of California. 3 * Copyright (c) 1987 Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -47,7 +47,7 @@ putenv(char *str)
47{ 47{
48 char **P, *cp; 48 char **P, *cp;
49 size_t cnt; 49 size_t cnt;
50 int offset; 50 int offset = 0;
51 51
52 for (cp = str; *cp && *cp != '='; ++cp) 52 for (cp = str; *cp && *cp != '='; ++cp)
53 ; 53 ;
@@ -57,7 +57,13 @@ putenv(char *str)
57 } 57 }
58 58
59 if (__findenv(str, (int)(cp - str), &offset) != NULL) { 59 if (__findenv(str, (int)(cp - str), &offset) != NULL) {
60 environ[offset] = str; 60 environ[offset++] = str;
61 /* could be set multiple times */
62 while (__findenv(str, (int)(cp - str), &offset)) {
63 for (P = &environ[offset];; ++P)
64 if (!(*P = *(P + 1)))
65 break;
66 }
61 return (0); 67 return (0);
62 } 68 }
63 69
@@ -84,9 +90,9 @@ putenv(char *str)
84int 90int
85setenv(const char *name, const char *value, int rewrite) 91setenv(const char *name, const char *value, int rewrite)
86{ 92{
87 char *C; 93 char *C, **P;
88 const char *np; 94 const char *np;
89 int l_value, offset; 95 int l_value, offset = 0;
90 96
91 for (np = name; *np && *np != '='; ++np) 97 for (np = name; *np && *np != '='; ++np)
92 ; 98 ;
@@ -99,6 +105,7 @@ setenv(const char *name, const char *value, int rewrite)
99 105
100 l_value = strlen(value); 106 l_value = strlen(value);
101 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { 107 if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
108 int tmpoff = offset + 1;
102 if (!rewrite) 109 if (!rewrite)
103 return (0); 110 return (0);
104#if 0 /* XXX - existing entry may not be writable */ 111#if 0 /* XXX - existing entry may not be writable */
@@ -108,9 +115,14 @@ setenv(const char *name, const char *value, int rewrite)
108 return (0); 115 return (0);
109 } 116 }
110#endif 117#endif
118 /* could be set multiple times */
119 while (__findenv(name, (int)(np - name), &tmpoff)) {
120 for (P = &environ[tmpoff];; ++P)
121 if (!(*P = *(P + 1)))
122 break;
123 }
111 } else { /* create new slot */ 124 } else { /* create new slot */
112 size_t cnt; 125 size_t cnt;
113 char **P;
114 126
115 for (P = environ; *P != NULL; P++) 127 for (P = environ; *P != NULL; P++)
116 ; 128 ;
@@ -143,7 +155,7 @@ unsetenv(const char *name)
143{ 155{
144 char **P; 156 char **P;
145 const char *np; 157 const char *np;
146 int offset; 158 int offset = 0;
147 159
148 if (!name || !*name) { 160 if (!name || !*name) {
149 errno = EINVAL; 161 errno = EINVAL;