diff --git a/src/flb_pack.c b/src/flb_pack.c index 28594b4f8d6..4fe9858bf03 100644 --- a/src/flb_pack.c +++ b/src/flb_pack.c @@ -839,6 +839,15 @@ int flb_metadata_pop_from_msgpack(msgpack_object **metadata, msgpack_unpacked *u return -1; } + if (upk->data.via.array.size < 2) { + return -1; + } + + if (upk->data.via.array.ptr[0].type != MSGPACK_OBJECT_ARRAY || + upk->data.via.array.ptr[0].via.array.size < 2) { + return -1; + } + *metadata = &upk->data.via.array.ptr[0].via.array.ptr[1]; *map = &upk->data.via.array.ptr[1]; @@ -854,12 +863,12 @@ static int pack_print_fluent_record(size_t cnt, msgpack_unpacked result) msgpack_object o; root = result.data; - if (root.type != MSGPACK_OBJECT_ARRAY) { + if (root.type != MSGPACK_OBJECT_ARRAY || root.via.array.size < 2) { return -1; } o = root.via.array.ptr[0]; - if (o.type != MSGPACK_OBJECT_ARRAY) { + if (o.type != MSGPACK_OBJECT_ARRAY || o.via.array.size != 2) { return -1; } diff --git a/src/flb_time.c b/src/flb_time.c index 6a1c94e0287..2aef2f4e723 100644 --- a/src/flb_time.c +++ b/src/flb_time.c @@ -405,6 +405,10 @@ int flb_time_pop_from_msgpack(struct flb_time *time, msgpack_unpacked *upk, return -1; } + if (upk->data.via.array.size < 2) { + return -1; + } + obj = upk->data.via.array.ptr[0]; if (obj.type == MSGPACK_OBJECT_ARRAY) { diff --git a/tests/internal/flb_time.c b/tests/internal/flb_time.c index e39f3154f66..d5e6bb5d6d6 100644 --- a/tests/internal/flb_time.c +++ b/tests/internal/flb_time.c @@ -466,8 +466,59 @@ void test_iana_zone_to_utc_offset() } } +/* flb_time_pop_from_msgpack must reject record arrays shorter than 2 + * elements instead of reading via.array.ptr[0]/ptr[1] out of bounds. */ +static void pop_from_array(const char *data, size_t size, int expect) +{ + struct flb_time tm; + msgpack_object *map; + msgpack_unpacked result; + int ret; + + msgpack_unpacked_init(&result); + msgpack_unpack_next(&result, data, size, NULL); + + ret = flb_time_pop_from_msgpack(&tm, &result, &map); + if (!TEST_CHECK(ret == expect)) { + TEST_MSG("got %d, expect %d", ret, expect); + } + + msgpack_unpacked_destroy(&result); +} + +void test_pop_from_msgpack_short_array() +{ + msgpack_packer mp_pck; + msgpack_sbuffer mp_sbuf; + + /* empty array: [] */ + msgpack_sbuffer_init(&mp_sbuf); + msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write); + msgpack_pack_array(&mp_pck, 0); + pop_from_array(mp_sbuf.data, mp_sbuf.size, -1); + msgpack_sbuffer_destroy(&mp_sbuf); + + /* single element: [ timestamp ] */ + msgpack_sbuffer_init(&mp_sbuf); + msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write); + msgpack_pack_array(&mp_pck, 1); + msgpack_pack_int(&mp_pck, SEC_32BIT); + pop_from_array(mp_sbuf.data, mp_sbuf.size, -1); + msgpack_sbuffer_destroy(&mp_sbuf); + + /* valid record: [ timestamp, map ] */ + msgpack_sbuffer_init(&mp_sbuf); + msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write); + msgpack_pack_array(&mp_pck, 2); + msgpack_pack_int(&mp_pck, SEC_32BIT); + msgpack_pack_map(&mp_pck, 0); + pop_from_array(mp_sbuf.data, mp_sbuf.size, 0); + msgpack_sbuffer_destroy(&mp_sbuf); +} + TEST_LIST = { { "flb_time_to_nanosec" , test_to_nanosec}, + { "pop_from_msgpack_short_array" , test_pop_from_msgpack_short_array}, { "flb_time_append_to_mpack_v1" , test_append_to_mpack_v1}, { "msgpack_to_time_int" , test_msgpack_to_time_int}, { "msgpack_to_time_double" , test_msgpack_to_time_double},