Skip to content

fix(fileutils): prevent stack buffer overflow in AbsPath#16

Open
Rakdos8 wants to merge 1 commit into
carbonengine:mainfrom
Rakdos8:fix/h1-abspath-buffer-overflow
Open

fix(fileutils): prevent stack buffer overflow in AbsPath#16
Rakdos8 wants to merge 1 commit into
carbonengine:mainfrom
Rakdos8:fix/h1-abspath-buffer-overflow

Conversation

@Rakdos8
Copy link
Copy Markdown

@Rakdos8 Rakdos8 commented May 15, 2026

Problem

AbsPath (POSIX path, used by CcpGetAbsolutePath) wrote into char[PATH_MAX] buffers with no bounds checking.
getcwd(src, …) followed by strcat(src, path) overflows the stack when cwd + path exceeds PATH_MAX (1024 on
macOS); src[len] = '/'; src[len+1] = 0; writes out of bounds when len == PATH_MAX-1; and strcpy(src, path)
(absolute path) plus strcpy(realPath, path) (on getcwd failure) are unbounded too. This is reachable on macOS (a
primary CI target) via CcpGetAbsolutePath, so it is a high-severity stack overflow driven entirely by path length.

Fix

AbsPath now receives the output buffer size (size_t realPathSize) — there is a single internal caller. src is
built with a bounded snprintf and the function returns an empty string when the combined path does not fit. The
getcwd failure path uses strncpy_s(…, _TRUNCATE) instead of strcpy, and there is an explicit guard before
writing into realPath. CcpGetAbsolutePath drops a dead line (a strcpy_s that was immediately overwritten) and
its unused variable, and now passes sizeof(buffer). Added #include <cstdio> in the POSIX block. Contract: when a
path is too long to fit, the function returns an empty string instead of overflowing.

Tests

Added two regression tests in tests/CcpFileUtils.cpp (GoogleTest, #if !_WIN32):
CcpGetAbsolutePathHandlesOverlongRelativePathSafely and CcpGetAbsolutePathHandlesOverlongAbsolutePathSafely, both
using 64 KB paths and expecting an empty result with no crash. Existing path-resolution tests are unaffected. Reviewed
manually; not compiled locally as the vcpkg toolchain is unavailable in this environment.

Scope

POSIX branch only — the Windows path uses GetFullPathNameW and is unchanged. No public API change.

getcwd + path concatenation and the absolute-path strcpy wrote into
fixed PATH_MAX buffers with no bounds check, allowing a stack overflow
for long paths. Build the working buffer with bounded snprintf, bail
out safely (empty result) when the path cannot fit, and pass the
output buffer size explicitly. Add regression tests for overlong
relative and absolute paths.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant