diff options
author | Vladimir Serbinenko <phcoder@gmail.com> | 2013-11-26 22:07:47 +0100 |
---|---|---|
committer | Peter Stuge <peter@stuge.se> | 2014-01-10 14:13:23 +0100 |
commit | 4b5012a4a2bf804d395ae3a72c76f50c4a9189db (patch) | |
tree | 1f2624a6fd80ebf9238d406f3535ea1f382a87f6 | |
parent | 697c1ed1ff93c3da040dd4bff0cbd1886bd5bf05 (diff) |
console/vsprintf: Implement snprintf
snprintf is a safe variant of sprintf. To avoid buffer overflows
we shouldn't use sprintf at all. But for now let's start by
implementing snprintf in first place.
Change-Id: Ic17d94b8cd91b72f66b84b0589a06b8abef5e5c9
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/4278
Tested-by: build bot (Jenkins)
Reviewed-by: Peter Stuge <peter@stuge.se>
-rw-r--r-- | src/console/vsprintf.c | 36 | ||||
-rw-r--r-- | src/include/string.h | 1 |
2 files changed, 29 insertions, 8 deletions
diff --git a/src/console/vsprintf.c b/src/console/vsprintf.c index 321ce81490..b1b6d475be 100644 --- a/src/console/vsprintf.c +++ b/src/console/vsprintf.c @@ -23,28 +23,34 @@ #include <console/vtxprintf.h> #include <trace.h> -struct vsprintf_context +struct vsnprintf_context { char *str_buf; + size_t buf_limit; }; static void str_tx_byte(unsigned char byte, void *data) { - struct vsprintf_context *ctx = data; - *ctx->str_buf = byte; - ctx->str_buf++; + struct vsnprintf_context *ctx = data; + if (ctx->buf_limit) { + *ctx->str_buf = byte; + ctx->str_buf++; + ctx->buf_limit--; + } } -static int vsprintf(char *buf, const char *fmt, va_list args) +static int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int i; - struct vsprintf_context ctx; + struct vsnprintf_context ctx; DISABLE_TRACE; ctx.str_buf = buf; + ctx.buf_limit = size ? size - 1 : 0; i = vtxdprintf(str_tx_byte, fmt, args, &ctx); - *ctx.str_buf = '\0'; + if (size) + *ctx.str_buf = '\0'; ENABLE_TRACE; @@ -57,7 +63,21 @@ int sprintf(char *buf, const char *fmt, ...) int i; va_start(args, fmt); - i = vsprintf(buf, fmt, args); + /* A trick: we have at most (size_t)-1 adressable space anyway, so + if we output so much we'll crash anyway. */ + i = vsnprintf(buf, -1, fmt, args); + va_end(args); + + return i; +} + +int snprintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = vsnprintf(buf, size, fmt, args); va_end(args); return i; diff --git a/src/include/string.h b/src/include/string.h index 77985e1325..dc125e19b0 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -17,6 +17,7 @@ int memcmp(const void *s1, const void *s2, size_t n); void *memchr(const void *s, int c, size_t n); #if !defined(__PRE_RAM__) int sprintf(char * buf, const char *fmt, ...); +int snprintf(char * buf, size_t size, const char *fmt, ...); #endif // simple string functions |