mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-11 22:49:58 +00:00
fix string leak in cli args_free (#2220)
args_parse zeroed every option's value pointer right before returning, so args_free's NULL check always skipped the free. Even without that, args_free was freeing the address of the caller's static variable (e.g. &ext_vars), not the string it points to. On Windows (_UNICODE builds) each ARGS_OPT_STRING value is a heap copy from unicode_to_ansi(), so -d, -x, -i, atom-quality-table and module-data args leaked on every run. On non-Windows the value just aliases argv, nothing to free. Removed the value-clearing loop in args_parse (nothing reads .value after parsing except args_free) and rewrote args_free to walk options->count entries and free the actual string pointers, gated on _UNICODE so it's a no-op elsewhere.
This commit is contained in:
+14
-7
@@ -257,9 +257,6 @@ int args_parse(args_option_t* options, int argc, const char_t** argv)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize to NULL the value pointers for all options.
|
|
||||||
for (; options->type != ARGS_OPT_END; options++) options->value = NULL;
|
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,11 +295,21 @@ void args_print_usage(args_option_t* options, int help_alignment)
|
|||||||
|
|
||||||
void args_free(args_option_t* options)
|
void args_free(args_option_t* options)
|
||||||
{
|
{
|
||||||
|
#ifdef _UNICODE
|
||||||
|
// On Windows the string values stored by args_parse_option are ANSI
|
||||||
|
// copies allocated by unicode_to_ansi(), so they must be released here.
|
||||||
|
// On non-Windows builds the string values point directly into argv,
|
||||||
|
// there's nothing to free.
|
||||||
for (; options->type != ARGS_OPT_END; options++)
|
for (; options->type != ARGS_OPT_END; options++)
|
||||||
{
|
{
|
||||||
if (options->type == ARGS_OPT_STRING && options->value != NULL)
|
if (options->type != ARGS_OPT_STRING || options->value == NULL)
|
||||||
{
|
continue;
|
||||||
free(options->value);
|
|
||||||
}
|
char** strings = (char**) options->value;
|
||||||
|
|
||||||
|
for (int i = 0; i < options->count; i++) free(strings[i]);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void) options;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user