lib/utilunix: free the words a command is cut into - #5152
Merged
mc-worker merged 2 commits intoSep 12, 2026
Merged
Conversation
my_system_make_arg_array() returns an array whose contents belong to two different owners: string literals for EXECUTE_AS_SHELL and for an empty command, the words str_tokenize() allocated otherwise. my_systemv_flags() frees it with g_ptr_array_free (args_array, TRUE), which frees the array and nothing in it, so every command that is not run through a shell leaves its words behind. Let the array own everything it holds and copy what it is given. A command of nothing but blanks tokenizes to nothing at all: str_tokenize() returns NULL, which g_ptr_array_index (args_array, 0) then dereferences. Such a command is no command at all, and now takes the same path as an empty one. Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
The mocked sigaction() never wrote into the oldact it was handed, so VERIFY_SIGACTION__IS_RESTORED() compared bytes that nobody had ever written, and mc_pstream_get_long_file_list_test never freed the pipe it opened. Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
Contributor
|
Thanks! |
mc-worker
requested review from
aborodin and
mc-worker
and removed request for
aborodin
September 12, 2026 09:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
my_system_make_arg_array()returns an array whose contents belong to twodifferent owners. For
EXECUTE_AS_SHELL, and for an empty command, it holdsstring literals and a
NULL; otherwise it holds the wordsstr_tokenize()allocated.
my_systemv_flags()then frees the array withg_ptr_array_free (args_array, TRUE), which frees the array and nothing in it, so every commandthat is not run through a shell leaves its words behind.
It is a small leak (one allocation per word of the command line), but it happens
on every
my_system()/my_systeml()/my_systemv_flags()call that runs aprogram directly — the user menu, the external editor and viewer, extfs helpers.
Change
The array owns everything it holds: it is created with
g_freeas its elementfree function, the literals are copied into it, and
my_systemv_flags()copiesthe caller's
argventries as it appends them. That is a handful ofg_strdup()next to a
fork()and anexecvp().A command of nothing but blanks is handled on the way:
str_tokenize()returnsNULLfor it, andg_ptr_array_index (args_array, 0)inmy_systemv_flags()then dereferences it. Such a command is the same as no command at all, and now
takes the same path as an empty one.
Two test-side fixes come with it, both found by the same valgrind run and both
unrelated to the leak:
sigaction()never wrote into theoldactit was handed, soVERIFY_SIGACTION__IS_RESTORED()compared bytes that nobody had ever written;mc_pstream_get_long_file_list_testnever freed the pipe it opened.Verified
Ubuntu 24.04,
--enable-werror: builds with no compiler warnings,make check69/69. The four
lib/utilunixtests undervalgrind --leak-check=full --errors-for-leak-kinds=definite --track-origins=yesreport nothing; before the change all four failed.