~ 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