Browse Source

Add length checking to prevent overflow in json_append_bkeys

master
Con Kolivas 9 years ago
parent
commit
77bf4b03d4
  1. 6
      src/connector.c
  2. 25
      src/libckpool.c
  3. 5
      src/libckpool.h

6
src/connector.c

@ -1204,7 +1204,7 @@ static void process_client_msg(cdata_t *cdata, char *buf, uint32_t msglen)
char *msg, *bkey = NULL; char *msg, *bkey = NULL;
int64_t client_id; int64_t client_id;
json_t *json_msg; json_t *json_msg;
int len; uint32_t len;
len = strlen(buf); len = strlen(buf);
if (likely(len > 4)) { if (likely(len > 4)) {
@ -1218,8 +1218,8 @@ static void process_client_msg(cdata_t *cdata, char *buf, uint32_t msglen)
return; return;
} }
if (unlikely(bkey)) { if (unlikely(bkey)) {
LOGWARNING("Bkey should be at %d, msglen %u", len + 1, msglen); len = msglen - (bkey - buf);
json_append_bkeys(json_msg, bkey); json_append_bkeys(json_msg, bkey, len);
} }
/* Extract the client id from the json message and remove its entry */ /* Extract the client id from the json message and remove its entry */

25
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); *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 ofs = BKEY_LENOFS + BKEY_LENLEN;
uint32_t msglen; uint32_t msglen;
msglen = bkey_len(bkey); msglen = bkey_len(bkey);
if (unlikely(!msglen || msglen > 0x80000000)) { if (unlikely(!msglen || msglen > 0x80000000)) {
LOGWARNING("Invalid msglen %u sent to json_append_bkey from %s %s:%d", LOGDEBUG("Invalid msglen %u sent to json_append_bkey from %s %s:%d",
msglen, file, func, line); msglen, file, func, line);
return; return false;
} }
while (ofs < msglen) { while (ofs < msglen) {
uint32_t binlen, *lenptr; 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; key = bkey + ofs;
LOGDEBUG("Found key %s @ ofs %u", key, ofs); LOGDEBUG("Found key %s @ ofs %u", key, ofs);
ofs += strlen(key) + 1; 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); lenptr = (uint32_t *)(bkey + ofs);
binlen = le32toh(*lenptr); binlen = le32toh(*lenptr);
LOGDEBUG("Found binlen %u @ ofs %u", binlen, ofs); LOGDEBUG("Found binlen %u @ ofs %u", binlen, ofs);
ofs += BKEY_LENLEN; 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); hex = bin2hex(bkey + ofs, binlen);
LOGDEBUG("Found hex %s @ ofs %u", hex, ofs); LOGDEBUG("Found hex %s @ ofs %u", hex, ofs);
json_set_string(val, key, hex); json_set_string(val, key, hex);
free(hex); free(hex);
ofs += binlen; ofs += binlen;
if (unlikely(ofs >= len)) {
LOGDEBUG("Unable to seek to bkey offset %u beyond length %d",
ofs, len);
return false;
}
} }
return true;
} }

5
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__) #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); 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__) #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); bool _json_append_bkeys(json_t *val, const char *bkey, const uint32_t len, const char *file,
#define json_append_bkeys(val, bkey) _json_append_bkeys(val, bkey, __FILE__, __func__, __LINE__) 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); void _json_check(json_t *val, json_error_t *err, const char *file, const char *func, const int line);

Loading…
Cancel
Save