From e697153d18531e6b12d110bc0c57658ae686fb08 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 1 Jul 2016 11:59:25 +0200 Subject: In Redis RDB check: log decompression errors. --- src/rdb.c | 6 +++++- src/redis-check-rdb.c | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/rdb.c b/src/rdb.c index 300d15602..9b4dcd027 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -45,6 +45,7 @@ extern int rdbCheckMode; void rdbCheckError(const char *fmt, ...); +void rdbCheckSetError(const char *fmt, ...); void rdbCheckThenExit(char *reason, int where) { if (!rdbCheckMode) { @@ -341,7 +342,10 @@ void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr) { /* Load the compressed representation and uncompress it to target. */ if (rioRead(rdb,c,clen) == 0) goto err; - if (lzf_decompress(c,clen,val,len) == 0) goto err; + if (lzf_decompress(c,clen,val,len) == 0) { + if (rdbCheckMode) rdbCheckSetError("Invalid LZF compressed string"); + goto err; + } zfree(c); if (plain || sds) { diff --git a/src/redis-check-rdb.c b/src/redis-check-rdb.c index 47897d788..e123b7f34 100644 --- a/src/redis-check-rdb.c +++ b/src/redis-check-rdb.c @@ -45,6 +45,8 @@ struct { unsigned long expires; /* Number of keys with an expire. */ unsigned long already_expired; /* Number of keys already expired. */ int doing; /* The state while reading the RDB. */ + int error_set; /* True if error is populated. */ + char error[1024]; } rdbstate; /* At every loading step try to remember what we were about to do, so that @@ -135,6 +137,17 @@ void rdbCheckInfo(const char *fmt, ...) { rdbstate.rio->processed_bytes : 0), msg); } +/* Used inside rdb.c in order to log specific errors happening inside + * the RDB loading internals. */ +void rdbCheckSetError(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vsnprintf(rdbstate.error, sizeof(rdbstate.error), fmt, ap); + va_end(ap); + rdbstate.error_set = 1; +} + /* During RDB check we setup a special signal handler for memory violations * and similar conditions, so that we can log the offending part of the RDB * if the crash is due to broken content. */ @@ -300,7 +313,11 @@ int redis_check_rdb(char *rdbfilename) { return 0; eoferr: /* unexpected end of file is handled here with a fatal exit */ - rdbCheckError("Unexpected EOF reading RDB file"); + if (rdbstate.error_set) { + rdbCheckError(rdbstate.error); + } else { + rdbCheckError("Unexpected EOF reading RDB file"); + } return 1; } -- cgit v1.2.1