Repository navigation
Batch: http_server_stop waits for any server; string_from_ptr refuses a bytes handle; macOS deployment target follows the OS - #3642
Merged
Conversation
http_server_stop joined only a server started with http_server_start_background_raw. A foreground http_server_start_raw run on another thread (an actor's) was signalled and left running, and the http_server_free that followed released the server under its accept loop and a pool worker still serving a keep-alive connection: a use after free in conn_serve / http_server_serve (ASan), a segfault on macOS and Linux (found by servirtium-vcr). The server now tracks its run per instance: a start begins it under run_lock (and refuses a server that is already running), the run ends it once its accept loop has returned and its pool, event loop and parking lot are joined, and broadcasts run_done. http_server_stop waits for that, whichever start began the run and on whatever thread, then joins a background thread. The run's own threads (the one running it, the pool workers, the proxy driver's threads, an HTTP/2 dispatch worker for its handler) register for the run, so a stop on one of them, from a handler or the monitor, only signals rather than waiting for a run that waits for it; a background server stopped from a handler used to hang there. http_server_free on such a thread while the server runs is fatal instead of a use after free. server_start_background now reports the C side's reason when it fails. tests/integration/http_server_stop_waits: a foreground server on an actor with a keep-alive connection held across stop and free, checking the stopped monitor fired before stop returned; stops from a handler, foreground and background; a refused second start. Fail on main (stop returns early; ASan use after free; macOS segfault 3/3), pass with this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its header bytes.string_from_ptr(src, n) wants a raw data pointer (bytes.data(b) or a C buffer), but a bytes handle is also a ptr, so passing the handle silently copied the AetherBytes struct header as text (bit servirtium-vcr Azure Key Vault test). AetherBytes now carries an 8-byte tag (cleared on free) and string_from_ptr panics on a live handle, naming bytes.to_string / bytes.data. The tag check short-circuits byte by byte, so raw buffers are never over-read. Docs (module comment, README, docs/api) say src must be a raw data pointer. Regression test covers the refused handle and the binary-safe correct forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test builds before running With MACOSX_DEPLOYMENT_TARGET unset, clang/ld target the SDK's macOS. When the SDK trails the running OS (a Command Line Tools or Xcode install that is a minor behind), linking a Homebrew dylib built for the running OS makes ld warn on every link: ld: warning: building for macOS-27.0, but linking with dylib '.../libnghttp2.14.dylib' which was built for newer version 27.2 The warning goes to the build's stderr and so into `ae run` output, which broke tests/integration/http_server_monitor (exact match on MONITOR-OK) and stopped `make ci` at step 5/11 on the Mac. build_gcc_cmd (the native POSIX path) now sets MACOSX_DEPLOYMENT_TARGET to the running OS's major.minor via kern.osproductversion when the caller has not set it. A caller's value wins, so a deliberate older target is kept; the zig cross path is untouched; release.yml pins no deployment target. The monitor test now builds each program, then runs it, so it compares the program's output and not the linker's; a failed build shows its own log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three fixes, one commit each, batched to save Actions minutes.
1.
std.http:http_server_stopwaits for the server, however it was started (88d650814)http_server_start_background_raw. For a foregroundhttp_server_start_rawon another thread (e.g. an actor), stop returned at once, and thehttp_server_freethat followed freed the server under the still-running accept loop and a pool worker serving a keep-alive connection. ASan: heap-use-after-free inconn_serve/http_server_serve. Found by servirtium-vcr.background_tidandbackground_tid_setare removed.tests/integration/http_server_stop_waits.foreground_actorholds a keep-alive connection across stop and free, 10 rounds;from_handlerstops from a handler in foreground and background modes, and checks the double-start refusal.2.
std.bytes:string_from_ptrrefuses a bytes handle (e7b6ab557)string_from_ptr(src, n)wants a raw data pointer, but a bytes handle is also aptr. Passing one silently copied theAetherBytesheader:string_from_ptr(b, 4)gave04000000whereto_string(b, 4)gives4100ff42.AetherBytesnow carries a tag, checked the wayis_aether_stringchecks strings (byte by byte, so a raw C buffer is never over-read). A live handle panics with a message pointing tobytes.to_string(b, n)orbytes.data(b).srcmust be a raw data pointer. Regression test included.3.
ae buildon macOS: the deployment target defaults to the running OS (4cfa58624)MACOSX_DEPLOYMENT_TARGETunset, clang targets the selected SDK's macOS (27.0 from an Xcode beta here). Homebrew builds its dylibs for the running OS (27.2), so every link against nghttp2 printed anld"built for newer version" warning intoae runoutput. That failedhttp_server_monitorand two examples, andmake cion macOS stopped at step 5.ae buildandae cflagsdefault the target to the running OS when the variable is unset; a value the caller sets still wins.http_server_monitornow builds first and compares only the program's output.Verified:
make cion cachyos (gcc 16,-Werror) with all three together: 714 C unit tests, 2203.aetests passed, 0 failed.make cipasses all 11 steps for the first time.🤖 Generated with Claude Code