Переглянути джерело

fix possible UB

A user isn't guaranteed to use the `der_..._multi()` in a correct fashion.
Therefor change the pattern in the library and terminate further vararg
processing immediately after the `EOL` marker is hit.

The previous changes introducing the function-`attribute(sentinel)` would
allow detecting this, but not all compilers have support for the attribute.

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 роки тому
батько
коміт
6ab01a8e8f

+ 5 - 4
src/pk/asn1/der/sequence/der_decode_sequence_multi.c

@@ -34,15 +34,16 @@ static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen
    x = 0;
    for (;;) {
        type = (ltc_asn1_type)va_arg(a1, int);
-       size = va_arg(a1, unsigned long);
-       data = va_arg(a1, void*);
-       LTC_UNUSED_PARAM(size);
-       LTC_UNUSED_PARAM(data);
 
        if (type == LTC_ASN1_EOL) {
           break;
        }
 
+       size = va_arg(a1, unsigned long);
+       data = va_arg(a1, void*);
+       LTC_UNUSED_PARAM(size);
+       LTC_UNUSED_PARAM(data);
+
        switch (type) {
            case LTC_ASN1_BOOLEAN:
            case LTC_ASN1_INTEGER:

+ 8 - 6
src/pk/asn1/der/sequence/der_encode_sequence_multi.c

@@ -35,15 +35,16 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
    x = 0;
    for (;;) {
        type = (ltc_asn1_type)va_arg(args, int);
-       size = va_arg(args, unsigned long);
-       data = va_arg(args, void*);
-       LTC_UNUSED_PARAM(size);
-       LTC_UNUSED_PARAM(data);
 
        if (type == LTC_ASN1_EOL) {
           break;
        }
 
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+       LTC_UNUSED_PARAM(size);
+       LTC_UNUSED_PARAM(data);
+
        switch (type) {
            case LTC_ASN1_BOOLEAN:
            case LTC_ASN1_INTEGER:
@@ -89,13 +90,14 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
    x = 0;
    for (;;) {
        type = (ltc_asn1_type)va_arg(args, int);
-       size = va_arg(args, unsigned long);
-       data = va_arg(args, void*);
 
        if (type == LTC_ASN1_EOL) {
           break;
        }
 
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+
        switch (type) {
            case LTC_ASN1_BOOLEAN:
            case LTC_ASN1_INTEGER: