diff options
author | Björn Svensson <bjorn.a.svensson@est.tech> | 2022-09-01 13:47:54 +0200 |
---|---|---|
committer | Michael Grunder <michael.grunder@gmail.com> | 2022-09-01 10:35:07 -0700 |
commit | 329eaf9bae314f8bc307c809340b262f67c2ce36 (patch) | |
tree | 39eea1f77463681efb497fdaccabf73a64c6e9d7 | |
parent | eaae7321c2c84c45f40ccb01233d299644f4e786 (diff) |
Fix heap-buffer-overflow issue in redisvFormatCommad
A command with a faulty formatting string that lacks the
conversion specifier results in a ASAN heap-buffer-overflow.
This was due to that strchr() matches on null-termination,
which triggers a continuation of the string parsing.
-rw-r--r-- | hiredis.c | 5 | ||||
-rw-r--r-- | test.c | 6 |
2 files changed, 10 insertions, 1 deletions
@@ -402,6 +402,11 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) { /* Copy va_list before consuming with va_arg */ va_copy(_cpy,ap); + /* Make sure we have more characters otherwise strchr() accepts + * '\0' as an integer specifier. This is checked after above + * va_copy() to avoid UB in fmt_invalid's call to va_end(). */ + if (*_p == '\0') goto fmt_invalid; + /* Integer conversion (without modifiers) */ if (strchr(intfmts,*_p) != NULL) { va_arg(ap,int); @@ -339,10 +339,14 @@ static void test_format_commands(void) { FLOAT_WIDTH_TEST(float); FLOAT_WIDTH_TEST(double); - test("Format command with invalid printf format: "); + test("Format command with unhandled printf format (specifier 'p' not supported): "); len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3); test_cond(len == -1); + test("Format command with invalid printf format (specifier missing): "); + len = redisFormatCommand(&cmd,"%-"); + test_cond(len == -1); + const char *argv[3]; argv[0] = "SET"; argv[1] = "foo\0xxx"; |