diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-26 14:05:36 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-03-26 14:05:36 +1100 |
commit | 1a929473ece26e9df642204390cf4a85368ec06a (patch) | |
tree | 0f80585e32b99cf1b66443b6226464d91f83957e | |
parent | 4b9b0757041053ef327a44a100ee5c33afc2bfd2 (diff) | |
download | mongo-1a929473ece26e9df642204390cf4a85368ec06a.tar.gz |
Add explicit size checks to public pack/unpack code: if all bytes are consumed and the next field is an integral type, we could read beyond the end of the buffer.
refs #1714
-rw-r--r-- | src/include/packing.i | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/include/packing.i b/src/include/packing.i index 9caa58ed2e1..b97b3a322ce 100644 --- a/src/include/packing.i +++ b/src/include/packing.i @@ -376,6 +376,11 @@ __pack_write( pad = pv->size - s; if (pv->type == 'U') { oldp = *pp; + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vpack_uint(pp, maxlen, s + pad)); maxlen -= (size_t)(*pp - oldp); } @@ -404,6 +409,11 @@ __pack_write( case 'i': case 'l': case 'q': + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vpack_int(pp, maxlen, pv->u.i)); break; case 'H': @@ -411,6 +421,11 @@ __pack_write( case 'L': case 'Q': case 'r': + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vpack_uint(pp, maxlen, pv->u.u)); break; case 'R': @@ -453,6 +468,11 @@ __unpack_read(WT_SESSION_IMPL *session, *pp += s; break; case 'U': + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vunpack_uint(pp, maxlen, &pv->u.u)); /* FALLTHROUGH */ case 'u': @@ -481,6 +501,11 @@ __unpack_read(WT_SESSION_IMPL *session, case 'i': case 'l': case 'q': + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vunpack_int(pp, maxlen, &pv->u.i)); break; case 'H': @@ -488,6 +513,11 @@ __unpack_read(WT_SESSION_IMPL *session, case 'L': case 'Q': case 'r': + /* + * Check that there is at least one byte available: the + * low-level routines treat zero length as unchecked. + */ + WT_SIZE_CHECK(1, maxlen); WT_RET(__wt_vunpack_uint(pp, maxlen, &pv->u.u)); break; case 'R': |