RTEMS | Draft: testsuites/psxtests: Add psxrealpath01 (!1441)

Sam Price (@TheSamPrice) gitlab at rtems.org
Fri Aug 21 01:30:27 UTC 2026



Sam Price created a merge request: https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1441

Project:Branches: TheSamPrice/rtems:test/psxrealpath01 to rtems/rtos/rtems:main
Author:   Sam Price



realpath() has no behavioural test; psxhdrs only checks that it compiles.
This adds one, covering two defects in the vendored
cpukit/libcsupport/src/contrib/realpath.c, which is a FreeBSD 9.1.0
snapshot from 2012-09-18 per the __FBSDID string it still carries.

Both are fixed in current FreeBSD and neither fix has been picked up:

  slen = readlink(resolved, symlink, sizeof(symlink));
  if (slen == 0) { errno = ENOENT; return (NULL); }
  if ((size_t)slen >= sizeof(symlink)) { errno = ENAMETOOLONG; return (NULL); }

Empty target.  readlink returns the byte count it wrote, so an empty
symlink target gives slen == 0 and the test at realpath.c:227,
symlink[slen - 1], reads one byte before a PATH_MAX stack buffer.
Nothing rejects an empty target on the way in: symlink() passes path1
through untouched, IMFS_symlink allocates strlen(target) + 1 without
inspecting it, and IMFS_readlink returns the count it copied.

Over-long target.  RTEMS reads with sizeof(symlink) - 1, so a longer
target is silently truncated and then resolved as if it were what the
link said.  RTEMS does have two ENAMETOOLONG checks, but both are inside
the if (p != NULL) block, so neither fires when the link is the last
component.

Measured on riscv/mbv, where PATH_MAX is 255:

  symlink("", "/emptylink") = 0, readlink = 0
  realpath("/emptylink/x")  = NULL, errno 2
  symlink(<271 byte target>, "/longlink") = 0
  realpath("/longlink")     = NULL, errno 2, where upstream gives ENAMETOOLONG

The ENOENT in the second case is the evidence: the target was truncated
to 254 bytes and the truncated path was resolved.

The test asserts the preconditions and the absence of a silent success,
and reports the rest.  With slen == 0 the branch taken depends on the
byte at symlink[-1], which is whatever the adjacent stack holds, so
asserting an expected string would be asserting on undefined behaviour
rather than testing it.  It passes as it stands, and keeps passing once
the file is re-imported.

Co-Authored-By: Claude Opus 5 (1M context) <noreply at anthropic.com>
Signed-off-by: Samuel Price <thesamprice at gmail.com>

-- 
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1441
You're receiving this email because of your account on gitlab.rtems.org. Unsubscribe from this thread: https://gitlab.rtems.org/-/sent_notifications/5-bdgw5y24z0sjo3cfh5mrde59z-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/cde570fa/attachment.htm>


More information about the bugs mailing list