| … | |
… | |
| 273 | |
273 | |
| 274 | int sandbox_setenv(char **env, char *name, char *val) { |
274 | int sandbox_setenv(char **env, char *name, char *val) { |
| 275 | char **tmp_env = env; |
275 | char **tmp_env = env; |
| 276 | char *tmp_string = NULL; |
276 | char *tmp_string = NULL; |
| 277 | |
277 | |
|
|
278 | /* XXX: We add the new variable to the end (no replacing). If this |
|
|
279 | * is changed, we need to fix sandbox_setup_environ() below */ |
| 278 | while (NULL != *tmp_env) |
280 | while (NULL != *tmp_env) |
| 279 | tmp_env++; |
281 | tmp_env++; |
| 280 | |
282 | |
| 281 | /* strlen(name) + strlen(val) + '=' + '\0' */ |
283 | /* strlen(name) + strlen(val) + '=' + '\0' */ |
| 282 | /* FIXME: Should probably free this at some stage - more neatness than |
284 | /* FIXME: Should probably free this at some stage - more neatness than |
| … | |
… | |
| 298 | * setting LD_PRELOAD parent side */ |
300 | * setting LD_PRELOAD parent side */ |
| 299 | char **sandbox_setup_environ(char *sandbox_dir, char *sandbox_lib, char *sandbox_rc, char *sandbox_log, |
301 | char **sandbox_setup_environ(char *sandbox_dir, char *sandbox_lib, char *sandbox_rc, char *sandbox_log, |
| 300 | char *sandbox_debug_log, char *sandbox_write_envvar, char *sandbox_predict_envvar) |
302 | char *sandbox_debug_log, char *sandbox_write_envvar, char *sandbox_predict_envvar) |
| 301 | { |
303 | { |
| 302 | int env_size = 0; |
304 | int env_size = 0; |
|
|
305 | int have_ld_preload = 0; |
| 303 | |
306 | |
| 304 | char **new_environ; |
307 | char **new_environ; |
| 305 | char **env_ptr = environ; |
308 | char **env_ptr = environ; |
| 306 | char *ld_preload_envvar = NULL; |
309 | char *ld_preload_envvar = NULL; |
|
|
310 | char *orig_ld_preload_envvar = NULL; |
| 307 | |
311 | |
| 308 | /* Unset these, as its easier than replacing when setting up our |
312 | /* Unset these, as its easier than replacing when setting up our |
| 309 | * new environment below */ |
313 | * new environment below */ |
| 310 | unsetenv(ENV_SANDBOX_DIR); |
314 | unsetenv(ENV_SANDBOX_DIR); |
| 311 | unsetenv(ENV_SANDBOX_LIB); |
315 | unsetenv(ENV_SANDBOX_LIB); |
| 312 | unsetenv(ENV_SANDBOX_BASHRC); |
316 | unsetenv(ENV_SANDBOX_BASHRC); |
| 313 | unsetenv(ENV_SANDBOX_LOG); |
317 | unsetenv(ENV_SANDBOX_LOG); |
| 314 | unsetenv(ENV_SANDBOX_DEBUG_LOG); |
318 | unsetenv(ENV_SANDBOX_DEBUG_LOG); |
| 315 | |
319 | |
| 316 | if (NULL != getenv("LD_PRELOAD")) { |
320 | if (NULL != getenv(ENV_LD_PRELOAD)) { |
|
|
321 | have_ld_preload = 1; |
|
|
322 | orig_ld_preload_envvar = getenv(ENV_LD_PRELOAD); |
|
|
323 | |
| 317 | /* FIXME: Should probably free this at some stage - more neatness |
324 | /* FIXME: Should probably free this at some stage - more neatness |
| 318 | * than a real leak that will cause issues. */ |
325 | * than a real leak that will cause issues. */ |
| 319 | ld_preload_envvar = malloc(strlen(getenv("LD_PRELOAD")) + |
326 | ld_preload_envvar = calloc(strlen(orig_ld_preload_envvar) + |
| 320 | strlen(sandbox_lib) + 2); |
327 | strlen(sandbox_lib) + 2, sizeof(char *)); |
| 321 | if (NULL == ld_preload_envvar) |
328 | if (NULL == ld_preload_envvar) |
| 322 | return NULL; |
329 | return NULL; |
| 323 | strncpy(ld_preload_envvar, sandbox_lib, strlen(sandbox_lib)); |
330 | snprintf(ld_preload_envvar, strlen(orig_ld_preload_envvar) + |
| 324 | strncat(ld_preload_envvar, " ", 1); |
331 | strlen(sandbox_lib) + 2, "%s %s", |
| 325 | strncat(ld_preload_envvar, getenv("LD_PRELOAD"), |
332 | sandbox_lib, orig_ld_preload_envvar); |
| 326 | strlen(getenv("LD_PRELOAD"))); |
|
|
| 327 | } else { |
333 | } else { |
| 328 | /* FIXME: Should probably free this at some stage - more neatness |
334 | /* FIXME: Should probably free this at some stage - more neatness |
| 329 | * than a real leak that will cause issues. */ |
335 | * than a real leak that will cause issues. */ |
| 330 | ld_preload_envvar = strndup(sandbox_lib, strlen(sandbox_lib)); |
336 | ld_preload_envvar = strndup(sandbox_lib, strlen(sandbox_lib)); |
| 331 | if (NULL == ld_preload_envvar) |
337 | if (NULL == ld_preload_envvar) |
| 332 | return NULL; |
338 | return NULL; |
| 333 | } |
339 | } |
|
|
340 | /* Do not unset this, as strange things might happen */ |
| 334 | unsetenv("LD_PRELOAD"); |
341 | /* unsetenv(ENV_LD_PRELOAD); */ |
| 335 | |
342 | |
| 336 | while (NULL != *env_ptr) { |
343 | while (NULL != *env_ptr) { |
| 337 | env_size++; |
344 | env_size++; |
| 338 | env_ptr++; |
345 | env_ptr++; |
| 339 | } |
346 | } |
| … | |
… | |
| 349 | sandbox_setenv(new_environ, ENV_SANDBOX_DIR, sandbox_dir); |
356 | sandbox_setenv(new_environ, ENV_SANDBOX_DIR, sandbox_dir); |
| 350 | sandbox_setenv(new_environ, ENV_SANDBOX_LIB, sandbox_lib); |
357 | sandbox_setenv(new_environ, ENV_SANDBOX_LIB, sandbox_lib); |
| 351 | sandbox_setenv(new_environ, ENV_SANDBOX_BASHRC, sandbox_rc); |
358 | sandbox_setenv(new_environ, ENV_SANDBOX_BASHRC, sandbox_rc); |
| 352 | sandbox_setenv(new_environ, ENV_SANDBOX_LOG, sandbox_log); |
359 | sandbox_setenv(new_environ, ENV_SANDBOX_LOG, sandbox_log); |
| 353 | sandbox_setenv(new_environ, ENV_SANDBOX_DEBUG_LOG, sandbox_debug_log); |
360 | sandbox_setenv(new_environ, ENV_SANDBOX_DEBUG_LOG, sandbox_debug_log); |
|
|
361 | /* If LD_PRELOAD was not set, set it here, else do it below */ |
|
|
362 | if (1 != have_ld_preload) |
| 354 | sandbox_setenv(new_environ, "LD_PRELOAD", ld_preload_envvar); |
363 | sandbox_setenv(new_environ, ENV_LD_PRELOAD, ld_preload_envvar); |
| 355 | |
364 | |
| 356 | if (!getenv(ENV_SANDBOX_DENY)) |
365 | if (!getenv(ENV_SANDBOX_DENY)) |
| 357 | sandbox_setenv(new_environ, ENV_SANDBOX_DENY, LD_PRELOAD_FILE); |
366 | sandbox_setenv(new_environ, ENV_SANDBOX_DENY, LD_PRELOAD_FILE); |
| 358 | |
367 | |
| 359 | if (!getenv(ENV_SANDBOX_READ)) |
368 | if (!getenv(ENV_SANDBOX_READ)) |
| … | |
… | |
| 379 | env_size++; |
388 | env_size++; |
| 380 | |
389 | |
| 381 | /* Now add the rest */ |
390 | /* Now add the rest */ |
| 382 | env_ptr = environ; |
391 | env_ptr = environ; |
| 383 | while (NULL != *env_ptr) { |
392 | while (NULL != *env_ptr) { |
|
|
393 | if ((1 == have_ld_preload) && |
|
|
394 | (strstr(*env_ptr, LD_PRELOAD_EQ) == *env_ptr)) |
|
|
395 | /* If LD_PRELOAD was set, and this is it in the original |
|
|
396 | * environment, replace it with our new copy */ |
|
|
397 | /* XXX: The following works as it just add whatever as |
|
|
398 | * the last variable to nev_environ */ |
|
|
399 | sandbox_setenv(new_environ, ENV_LD_PRELOAD, |
|
|
400 | ld_preload_envvar); |
|
|
401 | else |
| 384 | new_environ[env_size + (env_ptr - environ)] = *env_ptr; |
402 | new_environ[env_size + (env_ptr - environ)] = *env_ptr; |
| 385 | env_ptr++; |
403 | env_ptr++; |
| 386 | } |
404 | } |
| 387 | |
405 | |
| 388 | return new_environ; |
406 | return new_environ; |
| 389 | } |
407 | } |