aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-12-30 05:05:31 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-12-30 05:05:31 +0000
commit76ddc2e3e4837d0557fb6626394f87648e5f8c3b (patch)
treef545fe36c1ebc20c743ab28bc0df2b0f1d28b59d
parentd6e8f9450cf055f0abfa424c5aa9e5a7c30d6593 (diff)
downloadbusybox-w32-76ddc2e3e4837d0557fb6626394f87648e5f8c3b.tar.gz
busybox-w32-76ddc2e3e4837d0557fb6626394f87648e5f8c3b.tar.bz2
busybox-w32-76ddc2e3e4837d0557fb6626394f87648e5f8c3b.zip
libbb: add bb_unsetenv (taken from hush).
udhcpc: stop filtering environment passed to the script. crond: fix uncovered potential bug (failing unsetenv) mdev: fix uncovered potential bug (failing unsetenv) tcp, udpsvd: fix uncovered potential bug (failing unsetenv) function old new delta safe_setenv - 58 +58 bb_unsetenv - 55 +55 builtin_unset 139 138 -1 tcpudpsvd_main 1843 1830 -13 free_strings_and_unsetenv 87 53 -34 udhcp_run_script 1186 1133 -53 safe_setenv4 62 - -62 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 0/4 up/down: 113/-163) Total: -50 bytes
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/xfuncs_printf.c23
-rw-r--r--miscutils/crond.c12
-rw-r--r--networking/tcpudp.c3
-rw-r--r--networking/udhcp/script.c66
-rw-r--r--shell/hush.c14
-rw-r--r--util-linux/mdev.c3
7 files changed, 65 insertions, 57 deletions
diff --git a/include/libbb.h b/include/libbb.h
index e0541a731..e1a6d120b 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -377,6 +377,7 @@ void xsetuid(uid_t uid) FAST_FUNC;
377void xchdir(const char *path) FAST_FUNC; 377void xchdir(const char *path) FAST_FUNC;
378void xchroot(const char *path) FAST_FUNC; 378void xchroot(const char *path) FAST_FUNC;
379void xsetenv(const char *key, const char *value) FAST_FUNC; 379void xsetenv(const char *key, const char *value) FAST_FUNC;
380void bb_unsetenv(const char *key) FAST_FUNC;
380void xunlink(const char *pathname) FAST_FUNC; 381void xunlink(const char *pathname) FAST_FUNC;
381void xstat(const char *pathname, struct stat *buf) FAST_FUNC; 382void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
382int xopen(const char *pathname, int flags) FAST_FUNC FAST_FUNC; 383int xopen(const char *pathname, int flags) FAST_FUNC FAST_FUNC;
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 108e14043..46ae7ac60 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -333,6 +333,29 @@ void FAST_FUNC xsetenv(const char *key, const char *value)
333 bb_error_msg_and_die(bb_msg_memory_exhausted); 333 bb_error_msg_and_die(bb_msg_memory_exhausted);
334} 334}
335 335
336/* Handles "VAR=VAL" strings, even those which are part of environ
337 * _right now_
338 */
339void FAST_FUNC bb_unsetenv(const char *var)
340{
341 char *tp = strchr(var, '=');
342
343 if (!tp) {
344 unsetenv(var);
345 return;
346 }
347
348 /* In case var was putenv'ed, we can't replace '='
349 * with NUL and unsetenv(var) - it won't work,
350 * env is modified by the replacement, unsetenv
351 * sees "VAR" instead of "VAR=VAL" and does not remove it!
352 * horror :( */
353 tp = xstrndup(var, tp - var);
354 unsetenv(tp);
355 free(tp);
356}
357
358
336// Die with an error message if we can't set gid. (Because resource limits may 359// Die with an error message if we can't set gid. (Because resource limits may
337// limit this user to a given number of processes, and if that fills up the 360// limit this user to a given number of processes, and if that fills up the
338// setgid() will fail and we'll _still_be_root_, which is bad.) 361// setgid() will fail and we'll _still_be_root_, which is bad.)
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 732fbb147..12560fa36 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -252,14 +252,12 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
252/* We set environment *before* vfork (because we want to use vfork), 252/* We set environment *before* vfork (because we want to use vfork),
253 * so we cannot use setenv() - repeated calls to setenv() may leak memory! 253 * so we cannot use setenv() - repeated calls to setenv() may leak memory!
254 * Using putenv(), and freeing memory after unsetenv() won't leak */ 254 * Using putenv(), and freeing memory after unsetenv() won't leak */
255static void safe_setenv4(char **pvar_val, const char *var, const char *val /*, int len*/) 255static void safe_setenv(char **pvar_val, const char *var, const char *val)
256{ 256{
257 const int len = 4; /* both var names are 4 char long */
258 char *var_val = *pvar_val; 257 char *var_val = *pvar_val;
259 258
260 if (var_val) { 259 if (var_val) {
261 var_val[len] = '\0'; /* nuke '=' */ 260 bb_unsetenv(var_val);
262 unsetenv(var_val);
263 free(var_val); 261 free(var_val);
264 } 262 }
265 *pvar_val = xasprintf("%s=%s", var, val); 263 *pvar_val = xasprintf("%s=%s", var, val);
@@ -270,10 +268,10 @@ static void safe_setenv4(char **pvar_val, const char *var, const char *val /*, i
270static void SetEnv(struct passwd *pas) 268static void SetEnv(struct passwd *pas)
271{ 269{
272#if SETENV_LEAKS 270#if SETENV_LEAKS
273 safe_setenv4(&env_var_user, "USER", pas->pw_name); 271 safe_setenv(&env_var_user, "USER", pas->pw_name);
274 safe_setenv4(&env_var_home, "HOME", pas->pw_dir); 272 safe_setenv(&env_var_home, "HOME", pas->pw_dir);
275 /* if we want to set user's shell instead: */ 273 /* if we want to set user's shell instead: */
276 /*safe_setenv(env_var_user, "SHELL", pas->pw_shell, 5);*/ 274 /*safe_setenv(env_var_user, "SHELL", pas->pw_shell);*/
277#else 275#else
278 xsetenv("USER", pas->pw_name); 276 xsetenv("USER", pas->pw_name);
279 xsetenv("HOME", pas->pw_dir); 277 xsetenv("HOME", pas->pw_dir);
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index 3b73f213f..55a3e0899 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -85,8 +85,7 @@ static void undo_xsetenv(void)
85 char **pp = env_cur = &env_var[0]; 85 char **pp = env_cur = &env_var[0];
86 while (*pp) { 86 while (*pp) {
87 char *var = *pp; 87 char *var = *pp;
88 *strchrnul(var, '=') = '\0'; 88 bb_unsetenv(var);
89 unsetenv(var);
90 free(var); 89 free(var);
91 *pp++ = NULL; 90 *pp++ = NULL;
92 } 91 }
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index 4ae17fb8d..5d42a45db 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -119,7 +119,8 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p,
119 } 119 }
120 option += optlen; 120 option += optlen;
121 len -= optlen; 121 len -= optlen;
122 if (len <= 0) break; 122 if (len <= 0)
123 break;
123 dest += sprintf(dest, " "); 124 dest += sprintf(dest, " ");
124 } 125 }
125 return ret; 126 return ret;
@@ -130,9 +131,8 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p,
130static char **fill_envp(struct dhcpMessage *packet) 131static char **fill_envp(struct dhcpMessage *packet)
131{ 132{
132 int num_options = 0; 133 int num_options = 0;
133 int i, j; 134 int i;
134 char **envp; 135 char **envp, **curr;
135 char *var;
136 const char *opt_name; 136 const char *opt_name;
137 uint8_t *temp; 137 uint8_t *temp;
138 char over = 0; 138 char over = 0;
@@ -156,21 +156,16 @@ static char **fill_envp(struct dhcpMessage *packet)
156 num_options++; 156 num_options++;
157 } 157 }
158 158
159 envp = xzalloc(sizeof(char *) * (num_options + 5)); 159 curr = envp = xzalloc(sizeof(char *) * (num_options + 3));
160 j = 0; 160 *curr = xasprintf("interface=%s", client_config.interface);
161 envp[j++] = xasprintf("interface=%s", client_config.interface); 161 putenv(*curr++);
162 var = getenv("PATH");
163 if (var)
164 envp[j++] = xasprintf("PATH=%s", var);
165 var = getenv("HOME");
166 if (var)
167 envp[j++] = xasprintf("HOME=%s", var);
168 162
169 if (packet == NULL) 163 if (packet == NULL)
170 return envp; 164 return envp;
171 165
172 envp[j] = xmalloc(sizeof("ip=255.255.255.255")); 166 *curr = xmalloc(sizeof("ip=255.255.255.255"));
173 sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); 167 sprintip(*curr, "ip=", (uint8_t *) &packet->yiaddr);
168 putenv(*curr++);
174 169
175 opt_name = dhcp_option_strings; 170 opt_name = dhcp_option_strings;
176 i = 0; 171 i = 0;
@@ -178,31 +173,36 @@ static char **fill_envp(struct dhcpMessage *packet)
178 temp = get_option(packet, dhcp_options[i].code); 173 temp = get_option(packet, dhcp_options[i].code);
179 if (!temp) 174 if (!temp)
180 goto next; 175 goto next;
181 envp[j++] = alloc_fill_opts(temp, &dhcp_options[i], opt_name); 176 *curr = alloc_fill_opts(temp, &dhcp_options[i], opt_name);
177 putenv(*curr++);
182 178
183 /* Fill in a subnet bits option for things like /24 */ 179 /* Fill in a subnet bits option for things like /24 */
184 if (dhcp_options[i].code == DHCP_SUBNET) { 180 if (dhcp_options[i].code == DHCP_SUBNET) {
185 uint32_t subnet; 181 uint32_t subnet;
186 move_from_unaligned32(subnet, temp); 182 move_from_unaligned32(subnet, temp);
187 envp[j++] = xasprintf("mask=%d", mton(subnet)); 183 *curr = xasprintf("mask=%d", mton(subnet));
184 putenv(*curr++);
188 } 185 }
189 next: 186 next:
190 opt_name += strlen(opt_name) + 1; 187 opt_name += strlen(opt_name) + 1;
191 i++; 188 i++;
192 } 189 }
193 if (packet->siaddr) { 190 if (packet->siaddr) {
194 envp[j] = xmalloc(sizeof("siaddr=255.255.255.255")); 191 *curr = xmalloc(sizeof("siaddr=255.255.255.255"));
195 sprintip(envp[j++], "siaddr=", (uint8_t *) &packet->siaddr); 192 sprintip(*curr, "siaddr=", (uint8_t *) &packet->siaddr);
193 putenv(*curr++);
196 } 194 }
197 if (!(over & FILE_FIELD) && packet->file[0]) { 195 if (!(over & FILE_FIELD) && packet->file[0]) {
198 /* watch out for invalid packets */ 196 /* watch out for invalid packets */
199 packet->file[sizeof(packet->file) - 1] = '\0'; 197 packet->file[sizeof(packet->file) - 1] = '\0';
200 envp[j++] = xasprintf("boot_file=%s", packet->file); 198 *curr = xasprintf("boot_file=%s", packet->file);
199 putenv(*curr++);
201 } 200 }
202 if (!(over & SNAME_FIELD) && packet->sname[0]) { 201 if (!(over & SNAME_FIELD) && packet->sname[0]) {
203 /* watch out for invalid packets */ 202 /* watch out for invalid packets */
204 packet->sname[sizeof(packet->sname) - 1] = '\0'; 203 packet->sname[sizeof(packet->sname) - 1] = '\0';
205 envp[j++] = xasprintf("sname=%s", packet->sname); 204 *curr = xasprintf("sname=%s", packet->sname);
205 putenv(*curr++);
206 } 206 }
207 return envp; 207 return envp;
208} 208}
@@ -211,29 +211,25 @@ static char **fill_envp(struct dhcpMessage *packet)
211/* Call a script with a par file and env vars */ 211/* Call a script with a par file and env vars */
212void FAST_FUNC udhcp_run_script(struct dhcpMessage *packet, const char *name) 212void FAST_FUNC udhcp_run_script(struct dhcpMessage *packet, const char *name)
213{ 213{
214 int pid;
215 char **envp, **curr; 214 char **envp, **curr;
215 char *argv[3];
216 216
217 if (client_config.script == NULL) 217 if (client_config.script == NULL)
218 return; 218 return;
219 219
220 DEBUG("vfork'ing and execle'ing %s", client_config.script); 220 DEBUG("vfork'ing and exec'ing %s", client_config.script);
221 221
222 envp = fill_envp(packet); 222 envp = fill_envp(packet);
223 223
224 /* call script */ 224 /* call script */
225// can we use wait4pid(spawn(...)) here? 225 argv[0] = (char*) client_config.script;
226 pid = vfork(); 226 argv[1] = (char*) name;
227 if (pid < 0) return; 227 argv[2] = NULL;
228 if (pid == 0) { 228 wait4pid(spawn(argv));
229 /* close fd's? */ 229
230 /* exec script */ 230 for (curr = envp; *curr; curr++) {
231 execle(client_config.script, client_config.script, 231 bb_unsetenv(*curr);
232 name, NULL, envp);
233 bb_perror_msg_and_die("exec %s", client_config.script);
234 }
235 safe_waitpid(pid, NULL, 0);
236 for (curr = envp; *curr; curr++)
237 free(*curr); 232 free(*curr);
233 }
238 free(envp); 234 free(envp);
239} 235}
diff --git a/shell/hush.c b/shell/hush.c
index eafcbb4c9..3b87855b6 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -730,16 +730,8 @@ static void free_strings_and_unsetenv(char **strings, int unset)
730 v = strings; 730 v = strings;
731 while (*v) { 731 while (*v) {
732 if (unset) { 732 if (unset) {
733 char *copy; 733 debug_printf_env("unsetenv '%s'\n", *v);
734 /* *strchrnul(*v, '=') = '\0'; -- BAD 734 bb_unsetenv(*v);
735 * In case *v was putenv'ed, we can't
736 * unsetenv(*v) after taking out '=':
737 * it won't work, env is modified by taking out!
738 * horror :( */
739 copy = xstrndup(*v, strchrnul(*v, '=') - *v);
740 debug_printf_env("unsetenv '%s'\n", copy);
741 unsetenv(copy);
742 free(copy);
743 } 735 }
744 free(*v++); 736 free(*v++);
745 } 737 }
@@ -2937,7 +2929,7 @@ static void unset_local_var(const char *name)
2937 * is ro, and we cannot reach this code on the 1st pass */ 2929 * is ro, and we cannot reach this code on the 1st pass */
2938 prev->next = cur->next; 2930 prev->next = cur->next;
2939 debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); 2931 debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr);
2940 unsetenv(cur->varstr); 2932 bb_unsetenv(cur->varstr);
2941 if (!cur->max_len) 2933 if (!cur->max_len)
2942 free(cur->varstr); 2934 free(cur->varstr);
2943 free(cur); 2935 free(cur);
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 34cabc934..956de15ae 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -276,8 +276,7 @@ static void make_device(char *path, int delete)
276 putenv(s); 276 putenv(s);
277 if (system(command) == -1) 277 if (system(command) == -1)
278 bb_perror_msg_and_die("can't run '%s'", command); 278 bb_perror_msg_and_die("can't run '%s'", command);
279 s[4] = '\0'; 279 unsetenv("MDEV");
280 unsetenv(s);
281 free(s); 280 free(s);
282 free(command); 281 free(command);
283 } 282 }