diff options
author | Thomas Bertschinger <tahbertschinger@gmail.com> | 2024-01-11 23:57:29 -0700 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-01-12 15:04:13 -0500 |
commit | aefc2644017d85ec9b502fb4d10b917c2a0629ed (patch) | |
tree | c97fc2b6cb0dcf452fafa85ba2220fe212578d9e | |
parent | 076216c16b2cbf5ab774fa34a83e6ef5b9429a4b (diff) |
fix invalid write in pop_cmd()
The memmove() in pop_cmd() reads and writes beyond the end of argv.
This is basically harmless in the current C program; the environment
variable list immediately follows argv so all this does is unnecessarily
copy the beginning of that list.
However, this will become problematic once we start calling C functions
like fs_cmds() from Rust code. Then argv will be a Vec<String> (as
*mut *mut i8) and the memory layout will be different--in particular,
I don't think we can assume that a Vec<String> will be NULL-terminated
like argv always is--, meaning the invalid write could lead to heap
corruption.
Also, it doesn't look like full_cmd ever gets used after calling
pop_cmd() so I'm removing it here since it looks unneeded to me.
Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | bcachefs.c | 8 |
1 files changed, 3 insertions, 5 deletions
@@ -104,16 +104,14 @@ static void usage(void) " version Display the version of the invoked bcachefs tool\n"); } -static char *full_cmd; - static char *pop_cmd(int *argc, char *argv[]) { char *cmd = argv[1]; if (!(*argc < 2)) - memmove(&argv[1], &argv[2], *argc * sizeof(argv[0])); + memmove(&argv[1], &argv[2], (*argc - 2) * sizeof(argv[0])); (*argc)--; + argv[*argc] = NULL; - full_cmd = mprintf("%s %s", full_cmd, cmd); return cmd; } @@ -190,7 +188,7 @@ int main(int argc, char *argv[]) { raid_init(); - full_cmd = argv[0]; + char *full_cmd = argv[0]; /* Are we being called via a symlink? */ |