diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-11-06 12:33:38 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2018-11-10 02:47:19 +0100 |
commit | de6618a2713ef26f888762cbe6539cc65a393c7c (patch) | |
tree | 82d4a6ff2c9292568beb0925d4e6f98de1f4d5f6 | |
parent | fa8760705c3685a31a119c58b348364410433952 (diff) | |
download | rockbox-de6618a2713ef26f888762cbe6539cc65a393c7c.tar.gz rockbox-de6618a2713ef26f888762cbe6539cc65a393c7c.zip |
Fix vuprintf fix possible %s buffer over-read
when precision is not specified memchr recieved -1 for count
count is unsigned so it looks in a potentially very large area
for a terminator and returns this whole area if \0 is not found
Instead we should use memchr when precision is specified
and if precision is not specified use strlen
Fixes 60+Mb Config.cfg files
Change-Id: Ic4d1439334588f999c9071235430c42df2af5cc4
-rw-r--r-- | firmware/common/vuprintf.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/firmware/common/vuprintf.c b/firmware/common/vuprintf.c index 152dc93299..7dd9449e56 100644 --- a/firmware/common/vuprintf.c +++ b/firmware/common/vuprintf.c | |||
@@ -473,15 +473,20 @@ static inline const char * format_s(const void *str, | |||
473 | return NULL; /* wchar_t support for now */ | 473 | return NULL; /* wchar_t support for now */ |
474 | } | 474 | } |
475 | 475 | ||
476 | const char *s = str; | ||
477 | size_t len; | ||
476 | /* string length may be specified by precision instead of \0- | 478 | /* string length may be specified by precision instead of \0- |
477 | terminated; however, don't go past a \0 if one is there */ | 479 | terminated; however, don't go past a \0 if one is there */ |
478 | const char *s = str; | 480 | if (precision >= 0) { |
479 | size_t len = precision >= 0 ? precision : -1; | 481 | const char *nil = memchr(s, '\0', (size_t) precision); |
480 | 482 | ||
481 | const char *nil = memchr(s, '\0', len); | 483 | if (nil != NULL && (nil - s) < precision) |
482 | if (nil) { | 484 | len = nil - s; |
483 | len = nil - s; | 485 | else |
484 | } | 486 | len = precision; |
487 | } | ||
488 | else | ||
489 | len = strlen(s); | ||
485 | 490 | ||
486 | fmt_buf->length = len; | 491 | fmt_buf->length = len; |
487 | return s; | 492 | return s; |