Avoid undefined behavior in tlsexttest
authortb <tb@openbsd.org>
Wed, 5 Jul 2023 17:30:14 +0000 (17:30 +0000)
committertb <tb@openbsd.org>
Wed, 5 Jul 2023 17:30:14 +0000 (17:30 +0000)
An empty array cannot be initialized and it is an incomplete type, so the
sizeof() operator can't be applied to it. Therefore initialize it with a
zero byte and replace sizeof() use with lengths.

Slightly tweaked version of a patch by inoguchi in portable.
Discussed with bcook, beck, kettenis

regress/lib/libssl/tlsext/tlsexttest.c

index 2da1b64..e4da328 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tlsexttest.c,v 1.81 2023/04/27 10:53:58 tb Exp $ */
+/* $OpenBSD: tlsexttest.c,v 1.82 2023/07/05 17:30:14 tb Exp $ */
 /*
  * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
  * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -1774,8 +1774,11 @@ static const unsigned char tlsext_sni_client[] = {
        0x6c, 0x2e, 0x6f, 0x72, 0x67,
 };
 
+/* An empty array is an incomplete type and sizeof() is undefined. */
 static const unsigned char tlsext_sni_server[] = {
+       0x00,
 };
+static size_t tlsext_sni_server_len = 0;
 
 static int
 test_tlsext_sni_client(void)
@@ -1973,9 +1976,9 @@ test_tlsext_sni_server(void)
        if (!CBB_finish(&cbb, &data, &dlen))
                errx(1, "failed to finish CBB");
 
-       if (dlen != sizeof(tlsext_sni_server)) {
+       if (dlen != tlsext_sni_server_len) {
                FAIL("got server SNI with length %zu, "
-                   "want length %zu\n", dlen, sizeof(tlsext_sni_server));
+                   "want length %zu\n", dlen, tlsext_sni_server_len);
                goto err;
        }
 
@@ -1984,14 +1987,14 @@ test_tlsext_sni_server(void)
                fprintf(stderr, "received:\n");
                hexdump(data, dlen);
                fprintf(stderr, "test data:\n");
-               hexdump(tlsext_sni_server, sizeof(tlsext_sni_server));
+               hexdump(tlsext_sni_server, tlsext_sni_server_len);
                goto err;
        }
 
        free(ssl->session->tlsext_hostname);
        ssl->session->tlsext_hostname = NULL;
 
-       CBS_init(&cbs, tlsext_sni_server, sizeof(tlsext_sni_server));
+       CBS_init(&cbs, tlsext_sni_server, tlsext_sni_server_len);
        if (!client_funcs->parse(ssl, SSL_TLSEXT_MSG_SH, &cbs, &alert)) {
                FAIL("failed to parse server SNI\n");
                goto err;
@@ -3186,7 +3189,7 @@ test_tlsext_srtp_server(void)
 }
 #endif /* OPENSSL_NO_SRTP */
 
-unsigned char tlsext_clienthello_default[] = {
+static const unsigned char tlsext_clienthello_default[] = {
        0x00, 0x34, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
        0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d,
        0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x23,
@@ -3196,7 +3199,11 @@ unsigned char tlsext_clienthello_default[] = {
        0x04, 0x03, 0x02, 0x01, 0x02, 0x03,
 };
 
-unsigned char tlsext_clienthello_disabled[] = {};
+/* An empty array is an incomplete type and sizeof() is undefined. */
+static const unsigned char tlsext_clienthello_disabled[] = {
+       0x00,
+};
+static size_t tlsext_clienthello_disabled_len = 0;
 
 static int
 test_tlsext_clienthello_build(void)
@@ -3287,18 +3294,18 @@ test_tlsext_clienthello_build(void)
                goto err;
        }
 
-       if (dlen != sizeof(tlsext_clienthello_disabled)) {
+       if (dlen != tlsext_clienthello_disabled_len) {
                FAIL("got clienthello extensions with length %zu, "
                    "want length %zu\n", dlen,
-                   sizeof(tlsext_clienthello_disabled));
+                   tlsext_clienthello_disabled_len);
                compare_data(data, dlen, tlsext_clienthello_disabled,
-                   sizeof(tlsext_clienthello_disabled));
+                   tlsext_clienthello_disabled_len);
                goto err;
        }
        if (memcmp(data, tlsext_clienthello_disabled, dlen) != 0) {
                FAIL("clienthello extensions differs:\n");
                compare_data(data, dlen, tlsext_clienthello_disabled,
-                   sizeof(tlsext_clienthello_disabled));
+                   tlsext_clienthello_disabled_len);
                goto err;
        }