Skip to content

Commit 11cfeee

Browse files
authored
Merge pull request #733 from tbeu/add-int-overflow-check-to-vrefbuffer
Adding int overflow checks to vrefbuffer
2 parents 801f61c + d727658 commit 11cfeee

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

include/msgpack/v1/vrefbuffer.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class vrefbuffer {
5858
:m_ref_size(std::max(ref_size, detail::packer_max_buffer_size + 1)),
5959
m_chunk_size(chunk_size)
6060
{
61+
if((sizeof(chunk) + chunk_size) < chunk_size) {
62+
throw std::bad_alloc();
63+
}
64+
6165
size_t nfirst = (sizeof(iovec) < 72/2) ?
6266
72 / sizeof(iovec) : 8;
6367

@@ -141,7 +145,11 @@ class vrefbuffer {
141145
if(sz < len) {
142146
sz = len;
143147
}
144-
148+
149+
if(sizeof(chunk) + sz < sz){
150+
throw std::bad_alloc();
151+
}
152+
145153
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
146154
if(!c) {
147155
throw std::bad_alloc();
@@ -183,6 +191,10 @@ class vrefbuffer {
183191
{
184192
size_t sz = m_chunk_size;
185193

194+
if((sizeof(chunk) + sz) < sz){
195+
throw std::bad_alloc();
196+
}
197+
186198
chunk* empty = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
187199
if(!empty) {
188200
throw std::bad_alloc();

src/vrefbuffer.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
3030
ref_size > MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ?
3131
ref_size : MSGPACK_PACKER_MAX_BUFFER_SIZE + 1 ;
3232

33+
if((sizeof(msgpack_vrefbuffer_chunk) + chunk_size) < chunk_size) {
34+
return false;
35+
}
36+
3337
nfirst = (sizeof(struct iovec) < 72/2) ?
3438
72 / sizeof(struct iovec) : 8;
3539

@@ -135,6 +139,9 @@ int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
135139
sz = len;
136140
}
137141

142+
if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
143+
return -1;
144+
}
138145
chunk = (msgpack_vrefbuffer_chunk*)malloc(
139146
sizeof(msgpack_vrefbuffer_chunk) + sz);
140147
if(chunk == NULL) {
@@ -164,8 +171,13 @@ int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
164171
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
165172
{
166173
size_t sz = vbuf->chunk_size;
174+
msgpack_vrefbuffer_chunk* empty;
175+
176+
if((sizeof(msgpack_vrefbuffer_chunk) + sz) < sz){
177+
return -1;
178+
}
167179

168-
msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
180+
empty = (msgpack_vrefbuffer_chunk*)malloc(
169181
sizeof(msgpack_vrefbuffer_chunk) + sz);
170182
if(empty == NULL) {
171183
return -1;

test/msgpack_c.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,3 +1352,14 @@ TEST(MSGPACKC, unpack_array_uint64)
13521352
EXPECT_EQ(0xFFF0000000000001LL, obj.via.array.ptr[0].via.u64);
13531353
msgpack_zone_destroy(&z);
13541354
}
1355+
1356+
1357+
TEST(MSGPACKC, vref_buffer_overflow)
1358+
{
1359+
msgpack_vrefbuffer vbuf;
1360+
msgpack_vrefbuffer to;
1361+
size_t ref_size = 0;
1362+
size_t chunk_size = std::numeric_limits<size_t>::max();
1363+
EXPECT_FALSE(msgpack_vrefbuffer_init(&vbuf, ref_size, chunk_size));
1364+
EXPECT_EQ(-1, msgpack_vrefbuffer_migrate(&vbuf, &to));
1365+
}

test/msgpack_vref.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,14 @@ TEST(MSGPACK, vrefbuffer_small_int64)
264264
msgpack::vrefbuffer vbuf(0, 0);
265265
GEN_TEST_VREF(int64_t, vbuf);
266266
}
267+
268+
TEST(MSGPACK, vref_buffer_overflow)
269+
{
270+
size_t ref_size = 0;
271+
size_t chunk_size = std::numeric_limits<size_t>::max();
272+
char *buf = (char *)malloc(0x1000);
273+
ASSERT_THROW(msgpack::vrefbuffer vbuf(ref_size, chunk_size), std::bad_alloc);
274+
msgpack::vrefbuffer vbuf2(0, 0x1000);
275+
ASSERT_THROW(vbuf2.append_copy(buf, chunk_size), std::bad_alloc);
276+
free(buf);
277+
}

0 commit comments

Comments
 (0)