Skip to content

Fix RUSTSEC-2026-0382 and related dependency advisories - #124

Merged
egorsmkv merged 2 commits into
RustedBytes:masterfrom
CBoYXD:fix/rustls-webpki-0.103.16
Nov 2, 2026
Merged

egorsmkv merged 2 commits into
RustedBytes:masterfrom
CBoYXD:fix/rustls-webpki-0.103.16

Conversation

@CBoYXD

@CBoYXD CBoYXD commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Update Cargo.lock to use compatible patched releases:

Dependency Before After Advisory
rustls-webpki 0.103.15 0.103.16 RUSTSEC-2026-0382
rustls 0.23.45 0.23.46 RUSTSEC-2026-0346, RUSTSEC-2026-0347, RUSTSEC-2026-0348, RUSTSEC-2026-0349
tokio 1.53.1 1.53.3 RUSTSEC-2026-0386 (unsoundness warning)

cargo audit with a freshly fetched RustSec database (revision ee1a49a2769a24a596afc1c20cb33748d2769586):

  • Before: 5 vulnerabilities, 2 warnings; exit 1.
  • After: 0 vulnerabilities, 1 warning; exit 0.

The remaining warning is RUSTSEC-2025-0134 for rustls-pemfile 2.2.0 being unmaintained. It has no patched release; replacing it requires source changes beyond this lockfile update. No advisories are ignored.

Verified on Linux x86_64 with CPython 3.14.7 and Rust nightly-2026-09-25:

  • python scripts/run_rust_tests.py: 387 passed.
  • python scripts/run_rust_tests.py --all-features: 478 passed.
  • cargo clippy --all-targets --all-features --locked -- -D warnings: passed.
  • maturin build --locked: built and installed a CPython 3.14 wheel. The native extension's build paths identify all three patched crate versions.
  • python scripts/run_python_tests.py: 616 passed, 124 skipped, 126 deselected.
  • git diff --check: passed.

The other platform and Python-version CI matrix entries were not run locally.

Flaky macOS datagram test (fa1c4de)

The first CI run failed only macos / Python 3.14, in test_connected_datagram_close_releases_socket_before_callback: reconnecting the same UDP 4-tuple raised EADDRINUSE. The lockfile update did not cause it. Every add_reader()/add_writer() wait owns a duplicate of the descriptor and ran on the coordination thread, so remove_reader() only queued its cancellation and the kernel socket could outlive close(). Linux accepts the duplicate 4-tuple; macOS rejects it.

fa1c4de runs waits armed while the loop is running as tasks on the loop's own runtime, and remove_reader()/remove_writer() drop them before returning. Registrations made while the loop is stopped still wait on the coordination thread and move to the loop thread on re-arm or replacement. New tests check through /proc/self/fd that no duplicate survives remove_reader() or connection_lost, including registrations that move between the threads.

Verified on Linux x86_64 with CPython 3.14:

  • Closing a connected datagram transport 5 × 1000 times: before the fix, 19 rounds still had the socket open through a duplicate after connection_lost and 91 had one during the callback; after it, 0 and 0.
  • The three affected tests fail in 41 of 50 runs on d9de2a3 and pass in 200 of 200 runs on fa1c4de.
  • python scripts/run_python_tests.py: 727 passed, 12 skipped, 216 deselected (with the ecosystem packages installed).
  • python scripts/run_python_tests.py tests/ecosystem -m ecosystem: 78 passed, 39 skipped. AnyIO integration check: ok.
  • python scripts/run_rust_tests.py: 387 passed; --all-features: 478 passed.
  • cargo clippy --all-targets --all-features --locked -- -D warnings: passed; cargo clippy --lib --all-features --target x86_64-pc-windows-msvc -- -D warnings (type check only): passed.
  • Release builds, median of 5 runs on a shared host: a persistent add_reader() ping-pong went from 86k to 246k events/s, and a sock_recvfrom() UDP ping-pong from 67.6k to 69.7k round trips/s (within noise).

macOS was not run locally; the CI matrix covers it.

CBoYXD and others added 2 commits October 29, 2026 21:09
On Unix every add_reader()/add_writer() readiness wait owns a duplicate
of the descriptor. Those waits ran on the coordination thread, so
remove_reader() only queued their cancellation, and the duplicate (and
with it the kernel socket) could outlive the caller's close(). A closed
connected datagram transport could therefore still hold its 4-tuple
after connection_lost ran. macOS rejects reconnecting that 4-tuple with
EADDRINUSE, which made
test_connected_datagram_close_releases_socket_before_callback flaky.

Waits armed while the loop runs on its own thread are now tasks on the
loop's runtime, and remove_reader()/remove_writer() drop them before
returning. Registrations made while the loop is stopped still wait on
the coordination thread; a re-arm or replacement while running moves
them to the loop thread, and the old wait is cancelled where it runs.

The tests check through /proc/self/fd that no duplicate outlives
remove_reader() or connection_lost, including registrations that move
between the two threads.
@egorsmkv
egorsmkv merged commit 8a6a086 into RustedBytes:master Nov 2, 2026
44 checks passed
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.

2 participants