Test that SSL_poll does not report a stream as writable if it isn't

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)
This commit is contained in:
Matt Caswell 2025-04-09 13:08:09 +01:00
parent 4efd1a2682
commit 85a8eba567
2 changed files with 93 additions and 0 deletions

View 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))

View 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)
};