https://gitlab.synchro.net/main/sbbs/-/commit/af6907bf2241b68660b56a92
Modified Files:
src/sbbs3/jsexec.cpp load_cfg.c sbbsdefs.h src/sbbs3/scfg/scfg.c src/sbbs3/scfgdefs.h src/xpdev/dirwrap.c
Log Message:
Fix silent path truncation and a 1-byte overflow in _fullpath()
The POSIX _fullpath() bounds check counted the prefix and the path but
not the '/' inserted between them, so a cwd of exactly size-1-strlen(path) chars wrote size+1 bytes into a size-byte buffer. The separator has been
there since 7afb0cbbe45 (2003-03-20); the undercounting guard arrived with 3b11acf35a0 (2014-04-24). Count the separator, and replace the
strncat(target, path, size - 1) of 7afb0cbbe45 -- which passes a total
buffer size where strncat wants remaining space -- with strlcat().
Read the working directory into a local buffer instead of relying on getcwd(NULL, size), whose allocating form is a glibc extension, and report truncation in the absolute-path branch rather than returning a plausible-looking but wrong path.
On failure the function returned NULL after emptying the caller's buffer,
and callers that discarded the return then proceeded on an empty path.
jsexec did this at ed6db36fad9 (2024-02-05): a control directory whose
resolved path exceeded the buffer left scfg.ctrl_dir empty, and the only diagnostics were "!ERROR changing directory to: " and a text.dat ENOENT
that named neither the path nor the limit. prep_dir() did the same at 79604ea564a (2005-09-05), which silently blanked every directory derived
from ctrl_dir, and additionally passed the caller's buffer size as the
size of its own MAX_PATH+1 scratch buffer. Check the return at those
sites, in SCFG, and in isabspath(), which passed the NULL to stricmp().
Also replace prep_dir()'s strncpy() of 46e1efa2229 (2020-05-26), which
does not terminate on an exact fit, and detect truncation of the
base-plus-path join before it reaches backslashcolon(), which appends
without bounds-checking.
Size the resolved system directory paths in scfg_t with a new LEN_SYSDIR
rather than LEN_DIR (100). These hold absolute paths built from ctrl_dir, which is copied from a startup_t field already sized INI_MAX_VALUE_LEN, so
100 truncated in both directions. LEN_SYSDIR is not MAX_PATH, which is PATH_MAX (4096) on Linux: the terminal server instantiates scfg_t
MAX_NODES times in node_scfg[], where that would cost roughly 10MB.
node_path[] keeps LEN_DIR for the same reason and still truncates for sufficiently deep installs; it needs to become a pointer array.
scfg_t changes size, so sbbsctrl.exe and UserEdit.exe must be rebuilt alongside.
Co-Authored-By: Claude Opus 5 (1M context) <
[email protected]>
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)