From 18424818dffce9f5978c585e5dd1c75fe47e54c2 Mon Sep 17 00:00:00 2001 From: Don Ward Date: Sat, 26 Oct 2024 10:08:12 +0100 Subject: [PATCH] Fix bug in u_read() It was possible to overrun the strings region leading to corruption of memory. The new code checks for overrun and allocates a new buffer if it would occur. --- src/runtime/rposix.r | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/runtime/rposix.r b/src/runtime/rposix.r index dcd4f488c..1ca841750 100644 --- a/src/runtime/rposix.r +++ b/src/runtime/rposix.r @@ -2445,9 +2445,21 @@ dptr u_read(dptr f, int n, int fstatus, dptr d) /* Something is available: allocate another chunk */ if (i == 0) StrLoc(*d) = alcstr(NULL, bufsize); - else + else { /* Extend the string */ + /* We must guard against running over the end of the current string region. + * In that case, allocate a whole new buffer (which will result in a GC) + * and copy the existing buffer into it. Don't use alcstr() to do the copy + * because that might involve accessing potentially non-existent memory after + * the end of the (old) string region. + */ + if (DiffPtrs(strend,strfree) < bufsize) { + char *newb = alcstr(NULL, StrLen(*d) + bufsize); /* a GC will occur */ + memcpy(newb, StrLoc(*d), StrLen(*d)); + StrLoc(*d) = newb; + } else (void) alcstr(NULL, bufsize); + } tryagain: if (fstatus & Fs_Socket) {