• src/ssh/ssh-conn.c ssh-internal.h src/ssh/test/test_conn.c

    From Deucе@VERT to Git commit to main/sbbs/master on Tue May 5 09:31:09 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/fce249c31b7afd2d8930933f
    Modified Files:
    src/ssh/ssh-conn.c ssh-internal.h src/ssh/test/test_conn.c
    Log Message:
    DeuceSSH: setup_complete becomes atomic_bool to close a visibility race

    The DSSH_PARAM_ACCEPT_EARLY_DATA bypass condition reads ch->setup_
    complete in handle_channel_data / handle_channel_extended_data
    under buf_mtx, but the writer (app thread, end of dssh_chan_open / dssh_chan_zc_open) was setting it as a plain bool with no mutex
    held -- so the demux's mtx_lock(buf_mtx) acquire was synchronizing
    with the previous send_window_adjust unlock, not with the
    setup_complete = true store. Visibility was eventually established
    once the app thread next called any buf_mtx-acquiring API, but
    between those points the demux could see stale setup_complete ==
    false and bypass-deliver data that should have gone through normal
    window enforcement.

    Switch to atomic_bool with explicit release-store on the writer
    side and acquire-load on the reader side. Same publish/subscribe
    guarantee the mutex would give us, no contention, and the demux's
    existing buf_mtx acquire still covers all the other channel state
    it reads.

    accept_pre_window_data stays a plain bool: it's set BEFORE
    register_channel, and register_channel's channel_mtx release
    publishes it to any later find_channel acquire.

    The four rx_truncation/bypass tests in test_conn.c that poke
    setup_complete directly switch to atomic_store (relaxed
    default; the ordering doesn't matter for synthetic test setup).

    OpenSSL: 3410/3410 pass. Botan: 3411/3411 pass.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    ■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net