Bound everything parsed by the legacy ASN.1 stack.
crypto/asn1 routinely switches between int and long without overflow
checks. Fortunately, it funnels everything into a common entrypoint, so
we can uniformly bound all inputs to something which comfortably fits in
an int.
Change-Id: I340674c6b07820309dc5891024498878c82e225b
Reviewed-on: https://boringssl-review.googlesource.com/20366
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 9b9ee6d..2f5f132 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -56,6 +56,7 @@
#include <openssl/asn1.h>
+#include <limits.h>
#include <string.h>
#include <openssl/asn1t.h>
@@ -179,6 +180,14 @@
else
asn1_cb = 0;
+ /*
+ * Bound |len| to comfortably fit in an int. Lengths in this module often
+ * switch between int and long without overflow checks.
+ */
+ if (len > INT_MAX/2) {
+ len = INT_MAX/2;
+ }
+
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {