~ chicken-core (master) ca38cd44d03361a67fde225bdac90c3c296820cc
commit ca38cd44d03361a67fde225bdac90c3c296820cc
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Mon Jul 20 12:03:34 2026 +0200
Commit: Mario Domenech Goulart <mario@parenteses.org>
CommitDate: Mon Jul 20 20:19:34 2026 +0200
Return string with a freshly copied bytevector from ##sys#read-symbolic-link
The bytevector buffer in ##sys#read-symbolic-link was statically
allocated, as in, created once for a lexically scoped variable outside
the lambda. This buffer would then be destructively modified by
reading the link into it, and then converted to a proper string
using ##sys#buffer->string! which creates a wrapper for it.
Because ##sys#buffer->string! will simply create a wrapper string
object onto the bytevector, it re-uses the same bytevector every time.
The bytevector further gets hard-truncated by mutating the
bytevector's header so it is suddenly of a different size. When it
gets copied to the heap, it will be allocated at exactly that size.
Then, when read-symbolic-link gets called again on a link that points
to a file with a longer file name, it will scribble over the next
object in the heap, because it assumes the bytevector is still of
length FILENAME_MAX.
The fix is trivial: use ##sys#buffer->string (without a bang) to
ensure we copy the buffer's contents to a freshly allocated
bytevector of the right length.
Signed-off-by: Mario Domenech Goulart <mario@parenteses.org>
diff --git a/posixunix.scm b/posixunix.scm
index 3b6ee2b4..cf1cf970 100644
--- a/posixunix.scm
+++ b/posixunix.scm
@@ -751,7 +751,7 @@ static int set_file_mtime(C_word filename, C_word atime, C_word mtime)
buf)))
(if (fx< len 0)
(posix-error #:file-error location "cannot read symbolic link" fname)
- (##sys#buffer->string! buf len))))))
+ (##sys#buffer->string buf 0 len))))))
(set! chicken.file.posix#read-symbolic-link
(lambda (fname #!optional canonicalize)
Trap