Skip to content

Fix the default I/O context of TLS objects and SSL_set_rfd/wfd on DTLS - #11956

Open
Frauschi wants to merge 2 commits into
wolfSSL:masterfrom
Frauschi:fix-tls-unset-fd-stdin
Open

Frauschi wants to merge 2 commits into
wolfSSL:masterfrom
Frauschi:fix-tls-unset-fd-stdin

Conversation

@Frauschi

@Frauschi Frauschi commented Nov 2, 2026

Copy link
Copy Markdown
Member

With WOLFSSL_DTLS compiled in, InitSSL set the default IO context of every WOLFSSL, TLS included, to &ssl->buffers.dtlsCtx. EmbedReceive/EmbedSend read that as *(int*)ctx, and the first member of the DTLS context is zero, so a TLS object with no fd did its I/O on fd 0 (stdin) instead of failing. With stdin as an idle socket, test_tls13_apis hangs in wolfSSL_read_early_data.

  • Default IO context is now &ssl->rfd/&ssl->wfd, or the DTLS context only for DTLS methods. NetX, Mynewt and GNRC keep their port context, also in DTLS builds.
  • The OpenSSL compat wolfSSL_set_rfd/wolfSSL_set_wfd now wrap wolfSSL_set_read_fd/wolfSSL_set_write_fd. set_wfd on a DTLS object pointed the write context at ssl->wfd, which EmbedSendTo then read as a WOLFSSL_DTLS_CTX.

Testing

  • test_tls_unset_fd_no_stdin_io: puts a socket on fd 0 and checks a client with no fd, and one with only a write fd, fail with SOCKET_ERROR_E without touching fd 0; checks the default contexts of TLS and DTLS objects.
  • test_dtls_set_rfd_wfd: DTLS handshake start over SSL_set_rfd/SSL_set_wfd on a datagram socketpair.
  • Both fail without the fix. make check passes with default, --enable-dtls, --enable-all, and --enable-all --enable-cryptocb --enable-asynccrypt-sw.

With WOLFSSL_DTLS compiled in, InitSSL pointed IOCB_ReadCtx and
IOCB_WriteCtx at ssl->buffers.dtlsCtx for every WOLFSSL, TLS ones
included. EmbedReceive and EmbedSend read the socket as *(int*)ctx,
and the first member of WOLFSSL_DTLS_CTX is the zeroed peer address,
so a TLS object that never had an fd set did its I/O on fd 0 instead
of failing on -1. When stdin is an idle socket, an accept or connect
without an fd blocks forever; test_tls13_apis hits this through
wolfSSL_read_early_data on a server with no fd.

Choose the default IO context in one place for builds with and without
DTLS. NetX, Mynewt and GNRC keep their port context, and the socket
default is &ssl->rfd/&ssl->wfd, or the DTLS context when the method is
DTLS. Mynewt and GNRC objects in builds with DTLS now get the port
context their I/O callbacks expect instead of the DTLS one.

The new test checks the default contexts of a TLS and a DTLS object,
and puts a socket on fd 0 to check that a client with no fd, and one
with only a write fd, fail with SOCKET_ERROR_E without writing to or
reading from fd 0.
The OpenSSL compat wolfSSL_set_wfd only stored the fd in ssl->wfd and
pointed IOCB_WriteCtx at it, also for DTLS objects. EmbedSendTo casts
the write context to WOLFSSL_DTLS_CTX, so it read the socket, the peer
address and the sendto callback from the WOLFSSL fields that follow wfd.
wolfSSL_set_rfd handled DTLS but did not reset dtlsCtx.connected, and
neither checked ssl for NULL.

Make both wrappers around wolfSSL_set_read_fd and wolfSSL_set_write_fd,
which select the DTLS context and fill it in.
@Frauschi Frauschi self-assigned this Nov 2, 2026
Copilot AI balanced review requested due to automatic review settings November 2, 2026 12:31
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The regression test lacks a client PSK callback, causing PSK-only DTLS 1.2 builds with TLS 1.3 enabled to return SUITES_ERROR instead of the expected WOLFSSL_ERROR_WANT_READ.

1 open issue
What changed in this PR

This PR corrects wolfSSL’s default I/O contexts so TLS objects without file descriptors fail rather than access stdin, while preserving DTLS and platform-specific contexts.

Changes:

  • Select default I/O contexts according to the protocol and platform.
  • Delegate OpenSSL-compatible read/write descriptor setters to the DTLS-aware implementations.
  • Add regression tests for unset TLS descriptors and DTLS descriptor setters.
File Description
tests/​api/​test_tls.h Registers the unset-descriptor regression test.
tests/​api/​test_tls.c Checks default contexts and prevents unintended stdin I/O.
tests/​api/​test_dtls.h Registers the DTLS descriptor-setter test.
tests/​api/​test_dtls.c Tests DTLS handshake initiation through compatibility setters.
src/​ssl.c Reuses DTLS-aware descriptor setters.
src/​internal.c Selects protocol-appropriate default I/O contexts.

Review effort: Balanced

Comment thread tests/api/test_dtls.c Resolved
@Frauschi

Frauschi commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

@claude review

@Frauschi

Frauschi commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

@wolfSSL-Fenrir-bot review

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #11956

Scan targets checked: wolfssl-src, wolfssl-bugs
Not reviewed (no scan target covers them): tests/api/test_dtls.h, tests/api/test_tls.h
Coverage: 2 of 4 in-scope changed file(s) opened by the reviewer; not opened: tests/api/test_dtls.c, tests/api/test_tls.c

Fenrir result: Approved ✅

No new issues found in the changed files.

Advisory only — this automated result does not count as a GitHub approval.

Review tier: Lite

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this PR and didn't find any bugs. It changes the default I/O context for every WOLFSSL object in DTLS-enabled builds, which includes --enable-all, so a maintainer should still look at it before merge.

What was reviewed:

  • InitSSL: NetX, Mynewt and GNRC still get their port contexts. Without those ports, TLS objects default to &ssl->rfd/&ssl->wfd, both initialized to -1 just above, and only methods with DTLS_MAJOR get dtlsCtx.
  • wolfSSL_set_rfd/wolfSSL_set_wfd now wrap wolfSSL_set_read_fd/wolfSSL_set_write_fd. On DTLS objects, set_wfd now updates dtlsCtx.wfd. Both setters now also NULL-check and reset dtlsCtx.connected, the same as wolfSSL_set_fd.
  • Both new tests restore fd 0, close their sockets on every path, and use C90 declarations.
Extended reasoning...

The change touches the default I/O callback context setup in InitSSL (src/internal.c), the OpenSSL-compat fd setters in src/ssl.c, and adds two API tests. It doesn't touch crypto, auth or parsing, but it changes the behavior of the core I/O path for every SSL object in DTLS-enabled builds. The diff is small, and in the configurations I traced it looks correct. I deferred because this changes a library-wide default. There is also an inline Copilot comment on the new DTLS test whose content and resolution I can't see.

@Frauschi

Frauschi commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

Jenkins retest this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants