Description
TomlString is allocated by toml_string_new(), and its str field is initialized only after toml_string_append_char() is called.
However, some parts of code assume that str field is always initialized and use it without NULL check, which can cause segfaults.
In toml_parse_int_or_float_or_time (crashing case)
If the input leads to no calls to toml_string_append_char(), but still reaches the parsing code where it uses str->str, program may segfault.
for example:
TomlValue* toml_parse_int_or_float_or_time(TomlParser *self)
{
TomlString *str = NULL;
...
str = toml_string_new();
// IF toml_string_append_char() is NEVER CALLED, str->str is NEVER INITIALIZED
...
if (type == 'i') {
char *end = NULL;
long long n = strtoll(str->str, &end, base); // str->str may be NULL, SEGFAULT!
...
Reproduction
- Create a file named
repro_use_before_initialization:
- Run parser:
toml_load_filename("./repro_use_before_initialization");
Actual behavior
- program crashes due to NULL pointer passed to strtoll
example output:
src/toml.c:1097:31: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/stdlib.h:203:14: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/toml.c:1097:31 in
AddressSanitizer:DEADLYSIGNAL
=================================================================
==12096==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fc37999445f bp 0x7fff5e98f270 sp 0x7fff5e98f220 T0)
==12096==The signal is caused by a READ memory access.
==12096==Hint: address points to the zero page.
#0 0x7fc37999445f in __GI_____strtol_l_internal stdlib/../stdlib/strtol_l.c:304:10
#1 0x5578ba0b720a in strtoll
#2 0x5578ba135f4a in toml_parse_int_or_float_or_time src/toml.c:1097:23
#3 0x5578ba13bb96 in toml_parse_value src/toml.c:1161:17
#4 0x5578ba148eee in toml_parse_key_value src/toml.c:1253:17
#5 0x5578ba156d79 in toml_parse src/toml.c:1674:17
#6 0x5578ba1575bf in toml_load_nstr_filename src/toml.c:1698:13
#7 0x5578ba158f7d in toml_load_file_filename src/toml.c:1743:13
#8 0x5578ba1592e3 in toml_load_filename src/toml.c:1772:13
Expected behavior
- input should be handled as invalid integer, program should set
TOML_ERR_SYNTAX and return NULL;
Fix suggestion
Description
TomlStringis allocated bytoml_string_new(), and its str field is initialized only aftertoml_string_append_char()is called.However, some parts of code assume that str field is always initialized and use it without NULL check, which can cause segfaults.
In
toml_parse_int_or_float_or_time(crashing case)If the input leads to no calls to
toml_string_append_char(), but still reaches the parsing code where it usesstr->str, program may segfault.for example:
Reproduction
repro_use_before_initialization:Actual behavior
example output:
Expected behavior
TOML_ERR_SYNTAXand return NULL;Fix suggestion
NULL check
str->strbefore using itor initialize
str->strintoml_string_new()so it is never NULL