lib: asn1.c: Prevent ASN1_ENUMERATED from wrapping.
authorJeremy Allison <jra@samba.org>
Thu, 23 Jan 2020 21:59:18 +0000 (13:59 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 29 Jan 2020 01:02:03 +0000 (01:02 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14238

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Douglas Bagnall <dbagnall@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Jan 29 01:02:04 UTC 2020 on sn-devel-184

lib/util/asn1.c

index 51da5424956672dec42e08213f4a4af90129f1f1..6ae54d4cf20aba6b08a6a7c8454baef1d9700472 100644 (file)
@@ -1024,9 +1024,10 @@ bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB
        return true;
 }
 
-/* read an integer */
+/* read a non-negative enumerated value */
 bool asn1_read_enumerated(struct asn1_data *data, int *v)
 {
+       unsigned int val_will_wrap = (0xFF << ((sizeof(int)*8)-8));
        *v = 0;
 
        if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
@@ -1035,7 +1036,22 @@ bool asn1_read_enumerated(struct asn1_data *data, int *v)
                if (!asn1_read_uint8(data, &b)) {
                        return false;
                }
+               if (*v & val_will_wrap) {
+                       /*
+                        * There is something already in
+                        * the top byte of the int. If we
+                        * shift left by 8 it's going to
+                        * wrap. Prevent this.
+                        */
+                       data->has_error = true;
+                       return false;
+               }
                *v = (*v << 8) + b;
+               if (*v < 0) {
+                       /* ASN1_ENUMERATED can't be -ve. */
+                       data->has_error = true;
+                       return false;
+               }
        }
        return asn1_end_tag(data);
 }