• src/sbbs3/xtrn.cpp src/xpdev/multisock.c

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Wed Jun 24 01:09:40 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/6816ce611ac542129603d4ac
    Modified Files:
    src/sbbs3/xtrn.cpp src/xpdev/multisock.c
    Log Message:
    Don't leak server listen sockets to spawned child processes (Windows)

    On Windows, sockets are inheritable by default and the timed-event / native external CreateProcess() path passed bInheritHandles=TRUE unconditionally, so every spawned child (a jsexec timed event, a native door, a Web Server CGI) inherited open handles to all server listen sockets. A long-lived child (e.g. a chat_llm_irc.js timed event) would then keep those sockets bound in the kernel after the parent (sbbsctrl/sbbscon) exited, leaving a ghost process that owned every Synchronet port and silently dropped incoming connections of all protocols.

    Two complementary fixes:

    - multisock.c: mark every listen socket (and accepted client socket)
    non-inheritable via SetHandleInformation(HANDLE_FLAG_INHERIT, 0) right after
    creation. This is the shared listen-socket path for all servers
    (Terminal/Mail/FTP/Web/Services), so children can no longer inherit a listen
    socket regardless of any CreateProcess inheritance flag.

    - xtrn.cpp external(): only pass bInheritHandles=TRUE when the child actually
    needs to inherit a handle we're sharing - the redirected stdio pipes
    (use_pipes) or the duplicated passthru/client socket that a native socket-door
    talks over. A timed event running jsexec shares neither and now gets FALSE.
    DOS doors communicate via named mailslots/events and need no inheritance.

    Fixes #1151.

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

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