lib/env: add function to save and restore unwanted variables
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
80a54e2b3e
commit
e113093ce9
|
@ -4,7 +4,14 @@
|
|||
#include "c.h"
|
||||
#include "nls.h"
|
||||
|
||||
struct ul_env_list;
|
||||
|
||||
extern void sanitize_env(void);
|
||||
extern void __sanitize_env(struct ul_env_list **org);
|
||||
|
||||
extern int env_list_setenv(struct ul_env_list *ls);
|
||||
extern void env_list_free(struct ul_env_list *ls);
|
||||
|
||||
extern char *safe_getenv(const char *arg);
|
||||
|
||||
|
||||
|
|
103
lib/env.c
103
lib/env.c
|
@ -50,8 +50,73 @@ static char * const noslash[] = {
|
|||
(char *) 0
|
||||
};
|
||||
|
||||
void
|
||||
sanitize_env(void)
|
||||
|
||||
struct ul_env_list {
|
||||
char *env;
|
||||
struct ul_env_list *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* Saves @name env.varable to @ls, returns pointer to the new head of the list.
|
||||
*/
|
||||
static struct ul_env_list *env_list_add(struct ul_env_list *ls0, const char *str)
|
||||
{
|
||||
struct ul_env_list *ls;
|
||||
char *p;
|
||||
size_t sz = 0;
|
||||
|
||||
if (!str || !*str)
|
||||
return ls0;
|
||||
|
||||
sz = strlen(str) + 1;
|
||||
p = malloc(sizeof(struct ul_env_list) + sz);
|
||||
|
||||
ls = (struct ul_env_list *) p;
|
||||
p += sizeof(struct ul_env_list);
|
||||
memcpy(p, str, sz);
|
||||
ls->env = p;
|
||||
|
||||
ls->next = ls0;
|
||||
return ls;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use setenv() for all stuff in @ls.
|
||||
*
|
||||
* It would be possible to use putenv(), but we want to keep @ls free()-able.
|
||||
*/
|
||||
int env_list_setenv(struct ul_env_list *ls)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
while (ls && rc == 0) {
|
||||
if (ls->env) {
|
||||
char *val = strchr(ls->env, '=');
|
||||
if (!val)
|
||||
continue;
|
||||
*val = '\0';
|
||||
rc = setenv(ls->env, val + 1, 0);
|
||||
*val = '=';
|
||||
}
|
||||
ls = ls->next;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void env_list_free(struct ul_env_list *ls)
|
||||
{
|
||||
while (ls) {
|
||||
struct ul_env_list *x = ls;
|
||||
ls = ls->next;
|
||||
free(x);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes unwanted variables from environ[]. If @ls is not NULL than stores
|
||||
* unwnated variables to the list.
|
||||
*/
|
||||
void __sanitize_env(struct ul_env_list **org)
|
||||
{
|
||||
char **envp = environ;
|
||||
char * const *bad;
|
||||
|
@ -64,6 +129,8 @@ sanitize_env(void)
|
|||
for (cur = envp; *cur; cur++) {
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
|
||||
if (org)
|
||||
*org = env_list_add(*org, *cur);
|
||||
last = remote_entry(envp, cur - envp, last);
|
||||
cur--;
|
||||
break;
|
||||
|
@ -77,6 +144,8 @@ sanitize_env(void)
|
|||
continue;
|
||||
if (!strchr(*cur, '/'))
|
||||
continue; /* OK */
|
||||
if (org)
|
||||
*org = env_list_add(*org, *cur);
|
||||
last = remote_entry(envp, cur - envp, last);
|
||||
cur--;
|
||||
break;
|
||||
|
@ -84,6 +153,10 @@ sanitize_env(void)
|
|||
}
|
||||
}
|
||||
|
||||
void sanitize_env(void)
|
||||
{
|
||||
__sanitize_env(NULL);
|
||||
}
|
||||
|
||||
char *safe_getenv(const char *arg)
|
||||
{
|
||||
|
@ -116,6 +189,7 @@ int main(void)
|
|||
char copy[32];
|
||||
char *p;
|
||||
int retval = EXIT_SUCCESS;
|
||||
struct ul_env_list *removed = NULL;
|
||||
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
strcpy(copy, *bad);
|
||||
|
@ -124,7 +198,11 @@ int main(void)
|
|||
*p = '\0';
|
||||
setenv(copy, copy, 1);
|
||||
}
|
||||
sanitize_env();
|
||||
|
||||
/* removed */
|
||||
__sanitize_env(&removed);
|
||||
|
||||
/* check removal */
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
strcpy(copy, *bad);
|
||||
p = strchr(copy, '=');
|
||||
|
@ -136,6 +214,25 @@ int main(void)
|
|||
retval = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore removed */
|
||||
env_list_setenv(removed);
|
||||
|
||||
/* check restore */
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
strcpy(copy, *bad);
|
||||
p = strchr(copy, '=');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
p = getenv(copy);
|
||||
if (!p) {
|
||||
warnx("%s was not restored", copy);
|
||||
retval = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
env_list_free(removed);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue