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) {