GNU bug report logs - #75768
Missing assertions to detect access to GC-freed strings

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> protonmail.com>

Date: Wed, 22 Jan 2025 20:13:02 UTC

Severity: normal

Full log


Message #11 received at 75768 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: 75768 <at> debbugs.gnu.org
Subject: Re: Missing assertions to detect access to GC-freed strings
Date: Thu, 23 Jan 2025 17:44:54 +0000
"Pip Cet" <pipcet <at> protonmail.com> writes:

> Pip Cet <pipcet <at> protonmail.com> writes:
>
>> Even with this patch, we would fail to recognize impossible strings
>> automatically if even a single bit in the data pointer is set.  I don't
>> have a better solution yet, though, but the patch (to follow as soon as
>> this has a bug number) would have detected this particular problem a
>> little sooner.
>
> Patch follows, I've confirmed that it would have detected this problem

Sorry, wrong patch!

From 5018bdbf3729351f5273c7eecee3b67131aa2859 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet <at> protonmail.com>
Subject: [PATCH] Additional checks for access to freed strings (bug#75768)

* src/lisp.h (LIVE_STRING_P): New function.
(SDATA):
(SCHARS):
(STRING_BYTES):
(string_immovable_p): Use it in assertions.
---
 src/lisp.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/lisp.h b/src/lisp.h
index 28fa4c8037e..678f1ba0460 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1672,6 +1672,13 @@ STRING_SET_MULTIBYTE (Lisp_Object str)
   XSTRING (str)->u.s.size_byte = XSTRING (str)->u.s.size;
 }
 
+/* Should always return true.  */
+INLINE bool
+LIVE_STRING_P (Lisp_Object string)
+{
+  return XSTRING (string)->u.s.data != NULL;
+}
+
 /* Convenience functions for dealing with Lisp strings.  */
 
 /* WARNING: Use the 'char *' pointers to string data with care in code
@@ -1685,6 +1692,7 @@ STRING_SET_MULTIBYTE (Lisp_Object str)
 INLINE unsigned char *
 SDATA (Lisp_Object string)
 {
+  eassert (LIVE_STRING_P (string));
   return XSTRING (string)->u.s.data;
 }
 INLINE char *
@@ -1706,6 +1714,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new)
 INLINE ptrdiff_t
 SCHARS (Lisp_Object string)
 {
+  eassert (LIVE_STRING_P (string));
   ptrdiff_t nchars = XSTRING (string)->u.s.size;
   eassume (0 <= nchars);
   return nchars;
@@ -1717,6 +1726,7 @@ SCHARS (Lisp_Object string)
 INLINE ptrdiff_t
 STRING_BYTES (struct Lisp_String *s)
 {
+  eassert (LIVE_STRING_P (make_lisp_ptr (s, Lisp_String)));
 #ifdef GC_CHECK_STRING_BYTES
   ptrdiff_t nbytes = string_bytes (s);
 #else
@@ -1753,6 +1763,7 @@ CHECK_STRING_NULL_BYTES (Lisp_Object string)
 INLINE bool
 string_immovable_p (Lisp_Object str)
 {
+  eassert (LIVE_STRING_P (str));
   return XSTRING (str)->u.s.size_byte == -3;
 }
 
-- 
2.47.1





This bug report was last modified 239 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.