diff --git a/.gitignore b/.gitignore index b9dc789bf..f046aab4a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ Makefile .deps .libs +build + # Files generated by make. *.o *.so diff --git a/CHANGELOG.md b/CHANGELOG.md index d3342a06f..1b664b289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2026-08-25 version 7.0.2 + * Fix integer overflow on msgpack_unpacker_expand_buffer(). (#1182) + # 2026-06-09 version 7.0.1 * Set `INSTALL_INTERFACE` to `CMAKE_INSTALL_INCLUDEDIR` (#1177) diff --git a/README.md b/README.md index 594f76876..63a5038b1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ `msgpack` for C =================== -Version 7.0.1 [![Build Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=c_master)](https://github.com/msgpack/msgpack-c/actions) [![Build status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/c_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/c_master) +Version 7.0.2 [![Build Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=c_master)](https://github.com/msgpack/msgpack-c/actions) [![Build status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/c_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/c_master) [![codecov](https://codecov.io/gh/msgpack/msgpack-c/branch/c_master/graph/badge.svg)](https://app.codecov.io/gh/msgpack/msgpack-c/tree/c_master) It's like JSON but smaller and faster. diff --git a/appveyor.yml b/appveyor.yml index fc9fe09db..cc316d5bc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 7.0.1.{build} +version: 7.0.2.{build} branches: only: diff --git a/include/msgpack/version_master.h b/include/msgpack/version_master.h index 558a4e2c6..ad4460965 100644 --- a/include/msgpack/version_master.h +++ b/include/msgpack/version_master.h @@ -1,3 +1,3 @@ #define MSGPACK_VERSION_MAJOR 7 #define MSGPACK_VERSION_MINOR 0 -#define MSGPACK_VERSION_REVISION 1 +#define MSGPACK_VERSION_REVISION 2 diff --git a/src/unpack.c b/src/unpack.c index 9341cb08a..2d02a721c 100644 --- a/src/unpack.c +++ b/src/unpack.c @@ -442,7 +442,11 @@ bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) if(mpac->off == COUNTER_SIZE) { char* tmp; - size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE + size_t next_size; + if(size > SIZE_MAX - mpac->used) { + return false; + } + next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE while(next_size < size + mpac->used) { size_t tmp_next_size = next_size * 2; if (tmp_next_size <= next_size) { @@ -464,6 +468,9 @@ bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) char* tmp; size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE size_t not_parsed = mpac->used - mpac->off; + if(size > SIZE_MAX - not_parsed - COUNTER_SIZE) { + return false; + } while(next_size < size + not_parsed + COUNTER_SIZE) { size_t tmp_next_size = next_size * 2; if (tmp_next_size <= next_size) { diff --git a/test/streaming_c.cpp b/test/streaming_c.cpp index d75bfbe58..ebf733625 100644 --- a/test/streaming_c.cpp +++ b/test/streaming_c.cpp @@ -192,3 +192,54 @@ TEST(streaming, basic_with_size) msgpack_unpacker_free(unp); msgpack_sbuffer_free(buffer); } + +// https://github.com/msgpack/msgpack-c/issues/1181 +TEST(streaming, reserve_buffer_overflow_rewound) +{ + msgpack_unpacker mpac; + ASSERT_TRUE(msgpack_unpacker_init(&mpac, 8)); + + // off == COUNTER_SIZE path: size + used would wrap + size_t request = SIZE_MAX - 2; + EXPECT_FALSE(msgpack_unpacker_reserve_buffer(&mpac, request)); + + // a sane request still works + EXPECT_TRUE(msgpack_unpacker_reserve_buffer(&mpac, 64)); + EXPECT_GE(msgpack_unpacker_buffer_capacity(&mpac), static_cast(64)); + + msgpack_unpacker_destroy(&mpac); +} + +TEST(streaming, reserve_buffer_overflow_not_rewound) +{ + msgpack_unpacker mpac; + ASSERT_TRUE(msgpack_unpacker_init(&mpac, 8)); + + // consume part of the buffer so off != COUNTER_SIZE + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_int(&pk, 1); + msgpack_pack_int(&pk, 2); + + ASSERT_TRUE(msgpack_unpacker_reserve_buffer(&mpac, sbuf.size)); + memcpy(msgpack_unpacker_buffer(&mpac), sbuf.data, sbuf.size); + msgpack_unpacker_buffer_consumed(&mpac, sbuf.size); + + msgpack_unpacked result; + msgpack_unpacked_init(&result); + ASSERT_EQ(MSGPACK_UNPACK_SUCCESS, msgpack_unpacker_next(&mpac, &result)); + EXPECT_EQ(1, result.data.via.i64); + + size_t request = SIZE_MAX - 2; + EXPECT_FALSE(msgpack_unpacker_reserve_buffer(&mpac, request)); + + // remaining data must still be parsable + ASSERT_EQ(MSGPACK_UNPACK_SUCCESS, msgpack_unpacker_next(&mpac, &result)); + EXPECT_EQ(2, result.data.via.i64); + + msgpack_unpacked_destroy(&result); + msgpack_sbuffer_destroy(&sbuf); + msgpack_unpacker_destroy(&mpac); +}