[PATCH] autofs-5.1.9 - use execle instead of calling out to setenv.
Jun Eeo <[email protected]> Mon, 15 Sep 2025 13:43:07 +0100
| Newsgroups | org.kernel.vger.autofs |
|---|---|
| Message-ID | <[email protected]> |
---
include/macros.h | 4 +-
lib/macros.c | 91 ++++++++++++++++++++++++++++++++++++++--
modules/lookup_program.c | 14 +++++--
3 files changed, 101 insertions(+), 8 deletions(-)
diff --git a/include/macros.h b/include/macros.h
index 5a5486e..5584719 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -40,6 +40,8 @@ void macro_free_global_table(void);
void macro_free_table(struct substvar *table);
const struct substvar *
macro_findvar(const struct substvar *table, const char *str, int len);
-void macro_setenv(struct substvar *table);
+
+int clone_environ(char** envp, char*** envp_ptr);
+int macro_setenv(char*** envp, struct substvar *table);
#endif
diff --git a/lib/macros.c b/lib/macros.c
index 5def26d..684d155 100644
--- a/lib/macros.c
+++ b/lib/macros.c
@@ -495,11 +495,92 @@ macro_findvar(const struct substvar *table, const char *str, int len)
return NULL;
}
+/* Just to be on the safe side. */
+int clone_environ(char **const envp, char ***new_envp_ptr)
+{
+ if (envp == NULL) {
+ *new_envp_ptr = NULL;
+ return 0;
+ }
+
+ size_t envp_length = 0;
+ // How big is the existing envp?
+ for (char **ep = envp; *ep != NULL; ep++)
+ envp_length++;
+
+ char **copy = calloc(envp_length + 1, sizeof(char*));
+ if (copy == NULL)
+ return -ENOMEM;
+
+ size_t num_copied = 0;
+
+ // Copy the individual entries.
+ for (num_copied = 0; num_copied < envp_length; num_copied++) {
+ if (!(copy[num_copied] = strdup(envp[num_copied])))
+ goto error;
+ }
+
+ copy[envp_length] = NULL;
+ *new_envp_ptr = copy;
+ return 0;
+
+error:
+ for (size_t i = 0; i < num_copied; i++)
+ free(copy[i]);
+ free(copy);
+ return -ENOMEM;
+}
+
+int safe_setenv(char ***envp_ptr, const char *key, const char *val)
+{
+ char **envp = *envp_ptr;
+ size_t envp_length = 0;
+ if (envp != NULL) {
+ for (char **ep = envp; *ep != NULL; ep++)
+ envp_length++;
+ }
+
+ size_t key_len = strlen(key);
+ size_t val_len = strlen(val);
+ // include the '=' and terminating \0.
+ char *str = malloc(key_len + 1 + val_len + 1);
+ if (str == NULL)
+ return -ENOMEM;
+
+ memcpy(str, key, key_len);
+ str[key_len] = '=';
+ memcpy(str + key_len + 1, val, val_len);
+ str[key_len + 1 + val_len] = 0;
+
+ for (size_t i = 0; i < envp_length; i++) {
+ // Checking for [key]= in envp[i].
+ if (strncmp(str, envp[i], key_len + 1) == 0) {
+ free(envp[i]);
+ envp[i] = str;
+ return 0;
+ }
+ }
+
+ // Allocate and add to the end of envp.
+ // + 1 for the new entry, + 1 for NULL.
+ envp = reallocarray(envp, envp_length + 1 + 1, sizeof(char*));
+ if (envp == NULL) {
+ free(str);
+ return -ENOMEM;
+ }
+
+ envp[envp_length] = str;
+ envp[envp_length + 1] = NULL;
+ *envp_ptr = envp;
+ return 0;
+}
+
/* Set environment from macro variable table */
-void macro_setenv(struct substvar *table)
+int macro_setenv(char*** envp, struct substvar *table)
{
const struct substvar *sv = system_table;
const struct substvar *lv = table;
+ int rv;
/*
* First set environment from global table, matching local
@@ -507,16 +588,18 @@ void macro_setenv(struct substvar *table)
*/
while (sv) {
if (sv->def)
- setenv(sv->def, sv->val, 1);
+ if ((rv = safe_setenv(envp, sv->def, sv->val)))
+ return rv;
sv = sv->next;
}
/* Next set environment from the local table */
while (lv) {
if (lv->def)
- setenv(lv->def, lv->val, 1);
+ if ((rv = safe_setenv(envp, lv->def, lv->val)))
+ return rv;
lv = lv->next;
}
- return;
+ return 0;
}
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index fd90fb8..d8b0657 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -247,14 +247,22 @@ static char *lookup_one(struct autofs_point *ap,
* MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup
* the macro table.
*/
+ char** envp;
+ if (clone_environ(environ, &envp)) {
+ fprintf(stderr, "clone_environ failed.\n");
+ _exit(255);
+ }
if (ctxt->mapfmt && !strcmp(ctxt->mapfmt, MAPFMT_DEFAULT)) {
struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context;
/* Add standard environment as seen by sun map parser */
pctxt->subst = addstdenv(pctxt->subst, prefix);
- macro_setenv(pctxt->subst);
+ if (macro_setenv(&envp, pctxt->subst)) {
+ fprintf(stderr, "macro_setenv failed.\n");
+ _exit(255);
+ }
}
- execl(ctxt->mapname, ctxt->mapname, name, NULL);
- _exit(255); /* execl() failed */
+ execle(ctxt->mapname, ctxt->mapname, name, NULL, envp);
+ _exit(255); /* execle() failed */
}
close(pipefd[1]);
close(epipefd[1]);
--
2.43.7