json: fix buffer overrun in encoding helper

The bounds check failed to account for the additional space required
for the terminating NUL after the encoded value was written.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-04-21 14:56:52 -05:00 committed by Anas Nashif
commit a09f6ad54c
2 changed files with 23 additions and 2 deletions

View file

@ -875,7 +875,7 @@ static int append_bytes_to_buf(const char *bytes, size_t len, void *data)
{ {
struct appender *appender = data; struct appender *appender = data;
if (len > appender->size - appender->used) { if (len >= appender->size - appender->used) {
return -ENOMEM; return -ENOMEM;
} }

View file

@ -519,6 +519,26 @@ static void test_json_escape_bounds_check(void)
zassert_equal(ret, -ENOMEM, "Bounds check OK"); zassert_equal(ret, -ENOMEM, "Bounds check OK");
} }
static void test_json_encode_bounds_check(void)
{
struct number {
u32_t val;
} str = { 0 };
const struct json_obj_descr descr[] = {
JSON_OBJ_DESCR_PRIM(struct number, val, JSON_TOK_NUMBER),
};
/* Encodes to {"val":0}\0 for a total of 10 bytes */
u8_t buf[10];
ssize_t ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
&str, buf, 10);
zassert_equal(ret, 0, "Bounds check passed");
zassert_equal(strlen(buf), 9, "encoded value length");
ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
&str, buf, 9);
zassert_equal(ret, -ENOMEM, "Bounds check rejected");
}
void test_main(void) void test_main(void)
{ {
ztest_test_suite(lib_json_test, ztest_test_suite(lib_json_test,
@ -539,7 +559,8 @@ void test_main(void)
ztest_unit_test(test_json_escape_one), ztest_unit_test(test_json_escape_one),
ztest_unit_test(test_json_escape_empty), ztest_unit_test(test_json_escape_empty),
ztest_unit_test(test_json_escape_no_op), ztest_unit_test(test_json_escape_no_op),
ztest_unit_test(test_json_escape_bounds_check) ztest_unit_test(test_json_escape_bounds_check),
ztest_unit_test(test_json_encode_bounds_check)
); );
ztest_run_test_suite(lib_json_test); ztest_run_test_suite(lib_json_test);