From 77bf4b03d466115be868a7d4f5887124b919b487 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 27 Jan 2016 18:37:20 +1100 Subject: [PATCH] Add length checking to prevent overflow in json_append_bkeys --- src/connector.c | 6 +++--- src/libckpool.c | 25 +++++++++++++++++++++---- src/libckpool.h | 5 +++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/connector.c b/src/connector.c index 46bcf6ff..54ae59f5 100644 --- a/src/connector.c +++ b/src/connector.c @@ -1204,7 +1204,7 @@ static void process_client_msg(cdata_t *cdata, char *buf, uint32_t msglen) char *msg, *bkey = NULL; int64_t client_id; json_t *json_msg; - int len; + uint32_t len; len = strlen(buf); if (likely(len > 4)) { @@ -1218,8 +1218,8 @@ static void process_client_msg(cdata_t *cdata, char *buf, uint32_t msglen) return; } if (unlikely(bkey)) { - LOGWARNING("Bkey should be at %d, msglen %u", len + 1, msglen); - json_append_bkeys(json_msg, bkey); + len = msglen - (bkey - buf); + json_append_bkeys(json_msg, bkey, len); } /* Extract the client id from the json message and remove its entry */ diff --git a/src/libckpool.c b/src/libckpool.c index 09561daf..857d80c0 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -1406,16 +1406,17 @@ void _bkey_add_bin(char **bkey, const char *key, const char *bin, const int blen *lenptr = htole32(newlen); } -void _json_append_bkeys(json_t *val, const char *bkey, const char *file, const char *func, const int line) +bool _json_append_bkeys(json_t *val, const char *bkey, const uint32_t len, const char *file, + const char *func, const int line) { uint32_t ofs = BKEY_LENOFS + BKEY_LENLEN; uint32_t msglen; msglen = bkey_len(bkey); if (unlikely(!msglen || msglen > 0x80000000)) { - LOGWARNING("Invalid msglen %u sent to json_append_bkey from %s %s:%d", - msglen, file, func, line); - return; + LOGDEBUG("Invalid msglen %u sent to json_append_bkey from %s %s:%d", + msglen, file, func, line); + return false; } while (ofs < msglen) { uint32_t binlen, *lenptr; @@ -1425,16 +1426,32 @@ void _json_append_bkeys(json_t *val, const char *bkey, const char *file, const c key = bkey + ofs; LOGDEBUG("Found key %s @ ofs %u", key, ofs); ofs += strlen(key) + 1; + if (unlikely(ofs >= len)) { + LOGDEBUG("Unable to seek to bkey offset %u beyond length %d", + ofs, len); + return false; + } lenptr = (uint32_t *)(bkey + ofs); binlen = le32toh(*lenptr); LOGDEBUG("Found binlen %u @ ofs %u", binlen, ofs); ofs += BKEY_LENLEN; + if (unlikely(ofs >= len)) { + LOGDEBUG("Unable to seek to bkey offset %u beyond length %d", + ofs, len); + return false; + } hex = bin2hex(bkey + ofs, binlen); LOGDEBUG("Found hex %s @ ofs %u", hex, ofs); json_set_string(val, key, hex); free(hex); ofs += binlen; + if (unlikely(ofs >= len)) { + LOGDEBUG("Unable to seek to bkey offset %u beyond length %d", + ofs, len); + return false; + } } + return true; } diff --git a/src/libckpool.h b/src/libckpool.h index 65ba9fb1..03e0b69f 100644 --- a/src/libckpool.h +++ b/src/libckpool.h @@ -328,8 +328,9 @@ void _bkey_add_hex(char **bkey, const char *key, const char *hex, const char *fi #define bkey_add_hex(bkey, key, hex) _bkey_add_hex(&(bkey), key, hex, __FILE__, __func__, __LINE__) void _bkey_add_bin(char **bkey, const char *key, const char *bin, const int blen, const char *file, const char *func, const int line); #define bkey_add_bin(bkey, key, bin) _bkey_add_bin(&(bkey), key, bin, __FILE__, __func__, __LINE__) -void _json_append_bkeys(json_t *val, const char *bkey, const char *file, const char *func, const int line); -#define json_append_bkeys(val, bkey) _json_append_bkeys(val, bkey, __FILE__, __func__, __LINE__) +bool _json_append_bkeys(json_t *val, const char *bkey, const uint32_t len, const char *file, + const char *func, const int line); +#define json_append_bkeys(val, bkey, len) _json_append_bkeys(val, bkey, len, __FILE__, __func__, __LINE__) void _json_check(json_t *val, json_error_t *err, const char *file, const char *func, const int line);