Skip to content

read_env_file: remove filtered entries from the g/c list before freeing - #585

Merged
millert merged 1 commit into
sudo-project:mainfrom
iefa-m:env-file-gc-double-free
Oct 27, 2026
Merged

millert merged 1 commit into
sudo-project:mainfrom
iefa-m:env-file-gc-double-free

Conversation

@iefa-m

@iefa-m iefa-m commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

read_env_file() frees a restricted_env_file line that env_keep/env_check (or env_delete) filters out, but env_file_next_local() already put that string on the sudoers g/c list. With NO_LEAKS defined (--disable-leaks, --enable-sanitizer, the fuzzers), sudoers_gc_run() frees it again when the plugin is closed. To reproduce, point fuzz_policy's restricted_env_file at a file containing FOO_NOT_KEPT=1; ASan then reports "attempting double-free" in sudoers_gc_run, with the first free in read_env_file.

Remove the entry from the g/c list before freeing it, the same pairing editor.c uses. Production builds (no NO_LEAKS) are unaffected because sudoers_gc_run() is a no-op there. This is the only place in the tree that frees a g/c-tracked pointer without removing it first.

env_file_next_local() adds each line it returns to the sudoers
garbage collection list.  When read_env_file() drops a
restricted_env_file entry that is not allowed by env_keep/env_check
(or is matched by env_delete), it frees the string but leaves it on
the g/c list, so sudoers_gc_run() frees it a second time when the
plugin is closed.  This only affects builds with NO_LEAKS defined
(--disable-leaks, --enable-sanitizer and the fuzzers).
@millert
millert merged commit 3595b15 into sudo-project:main Oct 27, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants