Subject: bug#62009: 29.0.60; Emacs crashes on setf symbol-name

From: Ruijie Yu <[email-masked]>
Date: Tue, 07 Mar 2023 12:40:06 +0800

Daniel Mendler <[email-masked]> writes:

> Execute the following in the scratch buffer:
>
> (setf (aref (symbol-name 'car) 1) ?o)
>
> Emacs crashes with a segmentation fault. Is this a well-known issue? I
> could reproduce the problem on Emacs 27 and 29. Should there be some
> mechanism to protect the strings of symbols?
>
> I found the snippet on reddit:
> https://old.reddit.com/r/emacs/comments/11ix6yu/ive_found_what_ive_been_looking_for/jb4ah5v/

Can't access reddit, but can reproduce in recent master (6fb8a4dff7ef).

To test, first put this file under emacs.git/src/:

    $ make; cd src

Then do the following for each symbol:
                - setf
                - find-file
                - with-current-buffer
                - buffer-file-name

    $ ./emacs -Q -batch -l test.el -eval '(foo (quote setf))'
    [1] "setf"
    [2] "sxtf"

    $ ./emacs -Q -batch -l test.el -eval '(foo (quote find-file))'
    [1] "find-file"
    [2] "fxnd-file"

And these below below: aref, null, car, cdr, save-current-buffer

    $ ./emacs -Q -batch -l test.el -eval '(foo (quote aref))'
    [1] "aref"
    Fatal error 11: Segmentation fault
    Backtrace:
    ...

My observation is that symbols "introduced" via C defuns and defmacros
exhibit this problem, whereas those introduced via Elisp defuns and
defmacros do not.  No symbols introduced via defvars exhibit this
problem, as shown above with buffer-file-name.

Seeing that it is a segfault, maybe the setf is trying to modify
readonly memory produced by the C defuns and defmacros?  If that is the
case, *if* we allow such modifications, we should make the memory
readwrite; *otherwise* maybe we should no-op, warn, or err in setf and
friends when we see readonly memory blocks?

With this collection of GDB commands:

And this GDB command line option:

    $ gdb -x debug.gdb --batch --args ./emacs -Q -batch -l ../test.el -eval '(foo (quote car))' > car.backtrace

I get the backtrace (attached below) for setf + symbol-name + 'car as
reported by OP.

HTH.

--
Best,

RY