RTEMS | Draft: libcsupport: Take two upstream realpath() fixes from FreeBSD (!1444)
Sam Price (@TheSamPrice)
gitlab at rtems.org
Fri Aug 21 02:31:00 UTC 2026
Sam Price created a merge request: https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1444
Project:Branches: TheSamPrice/rtems:libcsupport/realpath-upstream-fixes to rtems/rtos/rtems:main
Author: Sam Price
RTEMS copied realpath() from FreeBSD in 2012 and has not updated it since.
The file still records where it came from, in its __FBSDID line:
release/9.1.0 rev 240647, 2012-09-18. FreeBSD has fixed two bugs in it
since then. This takes both fixes, in the form upstream uses.
Where these come from:
fix https://cgit.freebsd.org/src/tree/lib/libc/stdlib/realpath.c
test https://cgit.freebsd.org/src/tree/lib/libc/tests/gen/realpath2_test.c
First bug, a symlink pointing at the empty string. readlink() returns
how many bytes it wrote, so an empty target returns 0. The code then read
symlink[slen - 1], which is symlink[-1]: one byte before the buffer
starts. Upstream returns ENOENT before anything reads the buffer.
Second bug, a symlink whose target is too long. The code asked
readlink() for one byte less than the buffer holds, so a longer target
came back quietly cut short. realpath() then followed the shortened path
as though it were the real target and could return a path the symlink does
not point to. That matters because callers use realpath() to find out
what a path really refers to. Upstream returns ENAMETOOLONG.
Neither symlink is hard to create. symlink() does not inspect the target
and IMFS stores whatever it is handed.
The test is upstream's realpath_empty_symlink from realpath2_test.c,
rewritten for this test suite: RTEMS imports no ATF tests, so upstream's
cannot be dropped in as they are. It goes in fssymlink, which already
covers symlink behaviour and runs against five file systems, rather than
in a test of its own. Upstream's other four cases, realpath_null,
realpath_empty, realpath_buffer_overflow and realpath_partial, are not
about symlinks and are not brought over here.
The over-long case is new. Upstream has the fix but no test for it.
Each case is skipped when the file system will not create that link. That
is not hypothetical: JFFS2 rejects a target longer than PATH_MAX outright,
with ENAMETOOLONG, so the case cannot be reached there.
Measured on riscv/mbv over IMFS, JFFS2 and RFS. The over-long case used
to return errno 2, ENOENT, from resolving the truncated path, and now
returns errno 91, ENAMETOOLONG.
Signed-off-by: Samuel Price <thesamprice at gmail.com>
Assisted-by: Claude Opus 5 (1M context) <noreply at anthropic.com>
--
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1444
You're receiving this email because of your account on gitlab.rtems.org. Unsubscribe from this thread: https://gitlab.rtems.org/-/sent_notifications/5-6wit5xs5m7va79a8nb3lxalof-1d/unsubscribe | Manage all notifications: https://gitlab.rtems.org/-/profile/notifications | Help: https://gitlab.rtems.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20260821/26f5f4ff/attachment.htm>
More information about the bugs
mailing list