summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-03-26 14:05:36 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-03-26 14:05:36 +1100
commit1a929473ece26e9df642204390cf4a85368ec06a (patch)
tree0f80585e32b99cf1b66443b6226464d91f83957e
parent4b9b0757041053ef327a44a100ee5c33afc2bfd2 (diff)
downloadmongo-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.i30
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':