Skip to content

Commit 392ae0f

Browse files
committed
Avoid a double-free in fuzz_policy caused by the early env_init(NULL).
This adds an env_free() function to explicitly free both the old and new copies of the environment. It is really only needed by fuzz_policy, which calls the policy module multiple times.
1 parent 3bbc7c8 commit 392ae0f

3 files changed

Lines changed: 20 additions & 2 deletions

File tree

plugins/sudoers/env.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,20 @@ static const char *initial_keepenv_table[] = {
228228
NULL
229229
};
230230

231+
/*
232+
* Free our copy (or copies) of the environment.
233+
* This function is only safe to call after the command has executed.
234+
*/
235+
void
236+
env_free(void)
237+
{
238+
sudoers_gc_remove(GC_PTR, env.envp);
239+
free(env.envp);
240+
sudoers_gc_remove(GC_PTR, env.old_envp);
241+
free(env.old_envp);
242+
memset(&env, 0, sizeof(env));
243+
}
244+
231245
/*
232246
* Initialize env based on envp.
233247
*/
@@ -243,7 +257,10 @@ env_init(char * const envp[])
243257
sudoers_gc_remove(GC_PTR, env.old_envp);
244258
free(env.old_envp);
245259

246-
/* Reset to initial state but keep a pointer to what we allocated. */
260+
/*
261+
* Reset to initial state but keep a pointer to what we allocated
262+
* since it will be passed to execve(2).
263+
*/
247264
env.old_envp = env.envp;
248265
env.envp = NULL;
249266
env.env_size = 0;

plugins/sudoers/sudoers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,7 @@ sudoers_cleanup(void)
15141514
canon_path_free_cache();
15151515

15161516
/* We must free the cached environment before running g/c. */
1517-
env_init(NULL);
1517+
env_free();
15181518

15191519
/* Run garbage collector. */
15201520
sudoers_gc_run();

plugins/sudoers/sudoers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ extern const struct iolog_path_escape *sudoers_iolog_path_escapes;
414414
char **env_get(void);
415415
bool env_merge(const struct sudoers_context *ctx, char * const envp[]);
416416
bool env_swap_old(void);
417+
void env_free(void);
417418
bool env_init(char * const envp[]);
418419
bool init_envtables(void);
419420
bool insert_env_vars(char * const envp[]);

0 commit comments

Comments
 (0)