Repository navigation
fix(filesystem): ensure readdir names are NUL-terminated - #197
Conversation
eos_fs_readdir() copied the inode name with strncpy(e->name, name, EOS_PATH_MAX - 1). eos_fs_validate_path() accepts paths of up to EOS_PATH_MAX - 1 characters, and for a name of exactly that length strncpy writes no terminator, so e->name[EOS_PATH_MAX - 1] kept whatever the caller's buffer held. Callers reading the name as a string then ran past the end of the field. Terminate explicitly, as eos_fs_init() and eos_fs_rename() in the same file already do. Shorter names are unaffected: strncpy already zero-fills the rest of the buffer, so that byte was already NUL. The regression test creates a 127-character path, pre-fills the dirent with non-zero bytes, and checks the returned name is terminated and equal to the path. It fails on master and passes with this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Stewardship review (2026-11-01, acting-owner sweep): the fix itself is approved in principle, but this PR is held — it does not yet meet the merge bar (CI green on the head sha + linked closing issue). What checks out: the premise reproduces from the code exactly as described ( What blocks merging:
With a rebased, green head and a linked issue, this merges as-is — no code changes requested. |
…adme-matrix fix(filesystem): land #197 — ensure readdir names are NUL-terminated (rebased)
|
Superseded by #229, which has now merged — closing this PR. Your commits landed unchanged: #229's merge commit has this PR's head (e3cfeb6) as its first parent, so your work is in master exactly as you authored it, and #229's CI on current master is fully green. The rebase could not be pushed into this fork branch — the GitHub API returns 404 on git-data writes to fork branches even with maintainer edits enabled (verified 2026-11-02) — which is why the landing went through a same-repo PR instead. One process note: #229 was initially opened with a wrong description (a stale review note misdescribed this PR), caught and corrected on the PR itself the same day; the press report records it. The change that landed is exactly yours. Thank you for the fix and the well-built regression test. |
Summary
eos_fs_readdir()can return an entry whosenameis not NUL-terminated.It copies the inode name with
strncpy(e->name, name, EOS_PATH_MAX - 1).eos_fs_validate_path()accepts paths of up toEOS_PATH_MAX - 1(127) characters, and for a name of exactly that lengthstrncpywrites no terminator.e->name[EOS_PATH_MAX - 1]keeps whatever the caller's buffer held, so a caller that reads the name as a string (printf,strcmp,strlen) reads past the end of the field.Reproduced on
master(89300b6): create a 127-character directory, pre-fill theeos_dirent_twith'X', and read it back:Type of Change
Changes
services/filesystem/src/filesystem.c: terminate the name explicitly after the copy (one line), the same wayeos_fs_init()andeos_fs_rename()in this file already do.tests/test_filesystem.c: addtest_fs_readdir_terminates_longest_name, which creates a 127-character path, fills the dirent with non-zero bytes before eachreaddir, and checks that the returned name is terminated and equal to the path.Names shorter than 127 characters are unaffected:
strncpyalready zero-fills the rest of the buffer, so that byte was already NUL. No header, struct, signature or return value changes.Testing
WSL Ubuntu, gcc 13.3.0,
-DCMAKE_BUILD_TYPE=Debug -DEOS_BUILD_TESTS=ON:ctest, 50/50 passing, in both a plain Debug build and an ASan + UBSan buildmaster, output above)The new test fails on
masterand passes with the fix:Under ASan + UBSan: no AddressSanitizer or LeakSanitizer reports, and no UBSan reports outside the vendored ed25519 sources. The ed25519 reports are the same on
master.Pre-Submission Checklist
masterand none in the changed files.Related Issues
None. No existing issue covers this bug.
Additional Notes
test_filesystemstill printsALL FS TESTS PASSED (14/14), but it already ran 16 tests before this change. I left that out of this PR to keep it focused.