aboutsummaryrefslogtreecommitdiffstats
path: root/lib/env.c
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2024-08-27 13:07:56 +0200
committerKarel Zak <kzak@redhat.com>2024-09-04 13:39:03 +0200
commitaa789c1efcd28223308d010c830bc7f22c52927b (patch)
tree6a9a5391c955727b24fc955aef7d275d978ec8af /lib/env.c
parent3489e86248361611db214a7b866cdc8e9b1d9a7a (diff)
downloadutil-linux-aa789c1efcd28223308d010c830bc7f22c52927b.tar.gz
env: save parsed variables into ul_env_list
The struct ul_env_list is currently only used to store the value of env when sanitizing environ[]. It would be beneficial to also use the functions related to ul_env_list for other purposes. In order to do this, it is important to keep the NAME and VALUE components separate. * Accept non-terminated name and value for env_list_add(). * Add env_list_add_from_string() to add item to the list from a "name=value" string. * Add env_list_add_variable() to add item to the list using separate "name" and "value" strings. * Update __sanitize_env() to use env_list_add_from_string(). * Modify the test to use "abc" as the value instead of copying the variable name (with '=') to the value. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/env.c')
-rw-r--r--lib/env.c87
1 files changed, 59 insertions, 28 deletions
diff --git a/lib/env.c b/lib/env.c
index 2bdfe5697e..bab8822b0e 100644
--- a/lib/env.c
+++ b/lib/env.c
@@ -52,36 +52,74 @@ static char * const noslash[] = {
struct ul_env_list {
- char *env;
+ char *name;
+ char *value;
+
struct ul_env_list *next;
};
/*
- * Saves @name env.variable to @ls, returns pointer to the new head of the list.
+ * Saves to the list and returns a pointer to the new head of the list.
*/
-static struct ul_env_list *env_list_add(struct ul_env_list *ls0, const char *str)
+static struct ul_env_list *env_list_add( struct ul_env_list *ls0,
+ const char *name, size_t namesz,
+ const char *value, size_t valsz)
{
struct ul_env_list *ls;
- char *p;
- size_t sz = 0;
- if (!str || !*str)
+ ls = calloc(1, sizeof(struct ul_env_list) + namesz + valsz + 2);
+ if (!ls)
return ls0;
- sz = strlen(str) + 1;
- p = malloc(sizeof(struct ul_env_list) + sz);
- if (!p)
- return ls0;
+ ls->name = ((char *) ls) + sizeof(struct ul_env_list);
+ ls->value = ls->name + namesz + 1;
- ls = (struct ul_env_list *) p;
- p += sizeof(struct ul_env_list);
- memcpy(p, str, sz);
- ls->env = p;
+ memcpy(ls->name, name, namesz);
+ memcpy(ls->value, value, valsz);
ls->next = ls0;
return ls;
}
+
+/*
+ * Saves the @str (with the name=value string) to the @ls and returns a pointer
+ * to the new head of the list.
+ */
+static struct ul_env_list *env_list_add_from_string(struct ul_env_list *ls,
+ const char *str)
+{
+ size_t namesz = 0, valsz = 0;
+ const char *val;
+
+ if (!str || !*str)
+ return ls;
+
+ val = strchr(str, '=');
+ if (!val)
+ return NULL;
+ namesz = val - str;
+
+ val++;
+ valsz = strlen(val);
+
+ return env_list_add(ls, str, namesz, val, valsz);
+}
+
+/*
+ * Saves the @name and @value to @ls0 and returns a pointer to the new head of
+ * the list.
+ */
+struct ul_env_list *env_list_add_variable(
+ struct ul_env_list *ls,
+ const char *name, const char *value)
+{
+ if (!name || !*name)
+ return ls;
+
+ return env_list_add(ls, name, strlen(name), value, value ? strlen(value) : 0);
+}
+
/*
* Use env_from_fd() to read environment from @fd.
*
@@ -99,7 +137,7 @@ struct ul_env_list *env_from_fd(int fd)
p = buf;
while (rc > 0) {
- ls = env_list_add(ls, p);
+ ls = env_list_add_from_string(ls, p);
p += strlen(p) + 1;
rc -= strlen(p) + 1;
}
@@ -110,22 +148,14 @@ struct ul_env_list *env_from_fd(int fd)
/*
* 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 = '=';
- }
+ if (ls->name && ls->value)
+ rc = setenv(ls->name, ls->value, 0);
ls = ls->next;
}
return rc;
@@ -158,7 +188,7 @@ void __sanitize_env(struct ul_env_list **org)
for (bad = forbid; *bad; bad++) {
if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
if (org)
- *org = env_list_add(*org, *cur);
+ *org = env_list_add_from_string(*org, *cur);
last = remove_entry(envp, cur - envp, last);
cur--;
break;
@@ -173,7 +203,7 @@ void __sanitize_env(struct ul_env_list **org)
if (!strchr(*cur, '/'))
continue; /* OK */
if (org)
- *org = env_list_add(*org, *cur);
+ *org = env_list_add_from_string(*org, *cur);
last = remove_entry(envp, cur - envp, last);
cur--;
break;
@@ -217,12 +247,13 @@ int main(void)
int retval = EXIT_SUCCESS;
struct ul_env_list *removed = NULL;
+ /* define env. */
for (bad = forbid; *bad; bad++) {
strcpy(copy, *bad);
p = strchr(copy, '=');
if (p)
*p = '\0';
- setenv(copy, copy, 1);
+ setenv(copy, "abc", 1);
}
/* removed */