]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Test that SSL_poll does not report a stream as writable if it isn't
authorMatt Caswell <matt@openssl.org>
Wed, 9 Apr 2025 12:08:09 +0000 (13:08 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 11 Apr 2025 06:58:03 +0000 (07:58 +0100)
We consume all the credit and check the stream is no longer writeable

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/27319)

test/radix/quic_ops.c
test/radix/quic_tests.c

index e3167a565ba40760abecf00d6c3063a6ec9f23a5..d987cfeadec9a747d1636c0079b8559b4e5ab116 100644 (file)
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 #include "internal/sockets.h"
+#include <openssl/rand.h>
 
 static const unsigned char alpn_ossltest[] = {
     /* "\x08ossltest" (hex for EBCDIC resilience) */
@@ -565,6 +566,40 @@ err:
     return ok;
 }
 
+DEF_FUNC(hf_write_rand)
+{
+    int ok = 0, r;
+    SSL *ssl;
+    void *buf = NULL;
+    size_t buf_len, bytes_written = 0;
+
+    F_POP(buf_len);
+    REQUIRE_SSL(ssl);
+
+    while (buf_len > 0) {
+        size_t thislen = buf_len > 1024 ? 1024 : buf_len;
+
+        if (buf == NULL)
+            buf = OPENSSL_malloc(thislen);
+        if (!TEST_ptr(buf))
+            goto err;
+        if (!TEST_int_eq(RAND_bytes(buf, thislen), 1))
+            goto err;
+        r = SSL_write_ex(ssl, buf, thislen, &bytes_written);
+        if (!TEST_true(r)
+            || !check_consistent_want(ssl, r)
+            || !TEST_size_t_eq(bytes_written, thislen))
+            goto err;
+
+        buf_len -= thislen;
+    }
+
+    ok = 1;
+err:
+    OPENSSL_free(buf);
+    return ok;
+}
+
 DEF_FUNC(hf_write_ex2)
 {
     int ok = 0, r;
@@ -1112,6 +1147,11 @@ err:
      OP_PUSH_BUFP(buf, buf_len),                                \
      OP_FUNC(hf_write))
 
+#define OP_WRITE_RAND(name, buf_len)                            \
+    (OP_SELECT_SSL(0, name),                                    \
+     OP_PUSH_SIZE(buf_len),                                     \
+     OP_FUNC(hf_write_rand))
+
 #define OP_WRITE_B(name, buf)                                   \
     OP_WRITE(name, (buf), sizeof(buf))
 
index 2a29f1e80fe2751c451069aba0df555ae3509248..4fd207f0bd97432393e6bcaef72e4f1687aab3b8 100644 (file)
@@ -232,6 +232,58 @@ DEF_SCRIPT(ssl_poll,
     }
 }
 
+DEF_FUNC(check_writeable)
+{
+    int ok = 0;
+    SSL *ssl;
+    SSL_POLL_ITEM item;
+    size_t result_count = 0;
+    uint64_t expect;
+    const struct timeval z_timeout = {0}, *p_timeout = &z_timeout;
+
+    F_POP(expect);
+    REQUIRE_SSL(ssl);
+
+    item.desc      = SSL_as_poll_descriptor(ssl);
+    item.events    = SSL_POLL_EVENT_W;
+    item.revents   = 0;
+
+    /* Zero-timeout call. */
+    result_count = SIZE_MAX;
+    if (!TEST_true(SSL_poll(&item, 1, sizeof(SSL_POLL_ITEM),
+                            p_timeout, 0, &result_count)))
+        goto err;
+
+    ok = (!!(item.revents & SSL_POLL_EVENT_W) == expect);
+
+ err:
+    return ok;
+}
+
+DEF_SCRIPT(check_cwm, "check stream obeys cwm")
+{
+    OP_SIMPLE_PAIR_CONN();
+
+    /* Create the initial stream by writing some data */
+    OP_WRITE_RAND(C, 1024);
+
+    /* We should be writeable at the start */
+    OP_PUSH_U64(1);
+    OP_SELECT_SSL(0, C);
+    OP_FUNC(check_writeable);
+
+    /* Default stream cwm is 512k (we already sent 1k). Consume all the rest */
+    OP_WRITE_RAND(C, 511 * 1024);
+
+    /* Confirm we are no longer writeable */
+    OP_PUSH_U64(0);
+    OP_SELECT_SSL(0, C);
+    OP_FUNC(check_writeable);
+
+    /* We now expect writes to fail */
+    OP_WRITE_FAIL(C);
+}
+
 /*
  * List of Test Scripts
  * ============================================================================
@@ -240,4 +292,5 @@ static SCRIPT_INFO *const scripts[] = {
     USE(simple_conn)
     USE(simple_thread)
     USE(ssl_poll)
+    USE(check_cwm)
 };