• SMB: smb_t.file is hard-coded to 128 bytes, shorter than MAX_PATH on e

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Fri Sep 11 14:42:07 2026
    open https://gitlab.synchro.net/main/sbbs/-/issues/1240

    `smb_t.file` (`src/smblib/smbdefs.h:676`) holds the path plus base filename of a
    message or file base, and is hard-coded to 128 bytes:

    ```c
    char file[128]; /* Path and base filename (no extension) */ ```

    That is shorter than `MAX_PATH` on every platform Synchronet targets: 260 on Windows (`_MAX_PATH`), 1024 on macOS/BSD (`MAXPATHLEN`), 4096 on Linux (`PATH_MAX`). smblib itself already builds the filenames derived from this field
    in `MAX_PATH + 1` buffers (`smblib.c:1521`, `smblib.c:2115`, where it appends `.shd` / `.sdt` / `.sid` / `.sda` / `.sha` / `.sch` / `.ini` / `.hash`), so the struct field is the only undersized link in the chain.

    ## How it truncates

    Roughly 52 sites across the tree populate the field, all of them with a bounded printf, for example:

    ```c
    SAFEPRINTF(smb->file, "%smail", cfg->data_dir); // load_cfg.c:661
    SAFEPRINTF2(smb->file, "%s%s", cfg->sub[subnum]->data_dir, cfg->sub[subnum]->code); // load_cfg.c:667
    ```

    The 127-character bound is exceeded by the configured field widths alone, and has been for a long time:

    - `sub_t.data_dir` and `dir_t.data_dir` are `LEN_DIR + 1` (101), and `sub_t.code`
    / `dir_t.code` are `LEN_EXTCODE + 1` (33). A sub-board or directory with a
    per-area data directory can therefore produce up to 132 characters.
    - `cfg.data_dir` is `LEN_SYSDIR + 1`, capped at `MAX_PATH` as of 2cd36a8803
    (printing-38-wait, 2026-09-11), so `"%smail"` can reach `MAX_PATH + 4`.

    Because every site uses a bounded printf, the truncation is silent: no `last_error`, no log line, no non-zero return.

    ## Consequence

    `smb_open()` then operates on the truncated name. Either it fails with an ENOENT
    naming a path the sysop never configured, which is hard to recognize as a length
    problem, or, if two configured bases share their first 127 characters, both resolve to the same `.shd` / `.sdt` pair and one silently reads and writes the other's data.

    ## Suggested fix

    Size the field `MAX_PATH + 1`, matching the buffers smblib already uses for the filenames it derives from it.

    `smb_t` is a runtime structure and is never serialized (nothing writes the struct
    itself to disk), so this is not an on-disk format change. It does change `sizeof(smb_t)`, so every consumer has to be rebuilt together: sbbs.dll / libsbbs.so, the servers, smbutil, chksmb, fixsmb and sbbsecho. The Borland-built
    sbbsctrl.exe and UserEdit.exe do not reference smblib and are unaffected.

    ## How this surfaced

    While fixing the GCC `-Wformat-overflow` warnings that followed the wider `scfg_t` directory fields, one of the 31 sites was sbbsecho's `export_netmail()`,
    which built this path with a bare `sprintf()`. It was changed to `SAFEPRINTF()` at 3d5feda5b2 (cord-3-waiver, 2026-09-11) to match its peers. That silenced the diagnostic but not the truncation, which is what this issue tracks.

    -- *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Fri Sep 11 14:56:34 2026
    close https://gitlab.synchro.net/main/sbbs/-/issues/1240
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab note in main/sbbs on Fri Sep 11 14:56:34 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1240#note_10324

    Fixed in 3f86aa8a3f (soon-11-joke, 2026-09-11).

    The "Suggested fix" above was not quite right, and the correction is worth recording. `MAX_PATH + 1` is too large: the field is the stem, *without* extension, and smblib appends `.shd` / `.sdt` / `.sid` / `.sda` / `.sha` / `.sch` / `.ini` / `.hash` / `.lock` to it into `MAX_PATH + 1` buffers. Sizing the stem `MAX_PATH + 1` therefore does not remove the truncation, it just relocates it to the derived filenames.

    That is not a theoretical objection. Building the `MAX_PATH + 1` version first produced **17 new `-Wformat-overflow` reports in smbutil**, every one of them a four or five character extension appended to a now-`MAX_PATH` stem overflowing the buffer holding the result (`smbutil.c` lines 1218-1273, 1455-1492, 2039). Rebuilding with headroom reserved cleared all 17.

    The committed sizing reserves the longest extension, which is `.hash` (and `.lock`, the same length) at five characters counting the dot:

    ```c
    #define SMB_MAX_FILE_EXT_LEN 5
    char file[MAX_PATH + 1 - SMB_MAX_FILE_EXT_LEN];
    ```

    That is 256 bytes on Windows, 1020 on macOS/BSD, 4092 on Linux, so a derived filename is at most MAX_PATH characters and fits a `MAX_PATH + 1` buffer by construction.

    ## One consumer also needed fixing

    `chksmb`'s `main()` built its `.shd` name in a `char str[128]`. No compiler diagnostic reaches that one in either direction: `SAFEPRINTF` is a bounded call, so `-Wformat-overflow` does not apply to it, and the `-Wformat-truncation` level enabled by `-Wall` does not fire either. It simply truncated. Found by auditing every buffer in the tree that receives `smb_t.file`; the other eight (`smbfile.c`, `getmail.c`, `smblib.c` x2, `smbutil.c`, `filedat.c` x2, `userdat.c`) were already `MAX_PATH + 1`.

    Verified with a clean serial build on Linux: the five server shared objects, the 23 utility binaries, and scfg/uedit/umonitor, with no warnings and no errors.

    -- *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)