Check for overflows in ASN1_object_size().
authorDr. Stephen Henson <steve@openssl.org>
Mon, 1 Aug 2016 23:30:47 +0000 (00:30 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 2 Aug 2016 19:54:32 +0000 (20:54 +0100)
Reviewed-by: Richard Levitte <levitte@openssl.org>
(cherry picked from commit e9f17097e9fbba3e7664cd67e54eebf2bd438863)

crypto/asn1/asn1_lib.c

index 874b1af8b09a41c19986c71f18b5e2520cc8be00..87526541035c6bf6a60b92a0b4aeeacb9c82ca43 100644 (file)
@@ -256,26 +256,30 @@ static void asn1_put_length(unsigned char **pp, int length)
 
 int ASN1_object_size(int constructed, int length, int tag)
 {
-    int ret;
-
-    ret = length;
-    ret++;
+    int ret = 1;
+    if (length < 0)
+        return -1;
     if (tag >= 31) {
         while (tag > 0) {
             tag >>= 7;
             ret++;
         }
     }
-    if (constructed == 2)
-        return ret + 3;
-    ret++;
-    if (length > 127) {
-        while (length > 0) {
-            length >>= 8;
-            ret++;
+    if (constructed == 2) {
+        ret += 3;
+    } else {
+        ret++;
+        if (length > 127) {
+            int tmplen = length;
+            while (tmplen > 0) {
+                tmplen >>= 8;
+                ret++;
+            }
         }
     }
-    return (ret);
+    if (ret >= INT_MAX - length)
+        return -1;
+    return ret + length;
 }
 
 static int _asn1_Finish(ASN1_const_CTX *c)