dynamic-extent &rest called with no args leads to memory fault

Bug #1072112 reported by Ryan Pavlik
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
High
Unassigned

Bug Description

Tested with SBCL-1.1.0, x86_64, with --no-userinit:

This is SBCL 1.1.0, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (defun test (&rest args) (let ((var (car args))) (princ var)))

TEST
* (test)
CORRUPTION WARNING in SBCL pid 23136(tid 140737353864960):
Memory fault at 0 (pc=0x1000e2beac, sp=0x7ffff0b575a0)
The integrity of this image is possibly compromised.
Continuing with fingers crossed.

  :

*features*:

(:ANSI-CL :COMMON-LISP :SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS
 :SB-UNICODE :SB-EVAL :SB-SOURCE-LOCATIONS :IEEE-FLOATING-POINT
 :OS-PROVIDES-POLL :OS-PROVIDES-GETPROTOBY-R :OS-PROVIDES-SUSECONDS-T
 :OS-PROVIDES-BLKSIZE-T :OS-PROVIDES-PUTWC :OS-PROVIDES-DLADDR
 :OS-PROVIDES-DLOPEN :LITTLE-ENDIAN :MULTIPLY-HIGH-VOPS :MEMORY-BARRIER-VOPS
 :INLINE-CONSTANTS :FLOAT-EQL-VOPS :COMPLEX-FLOAT-VOPS :CYCLE-COUNTER
 :ALIEN-CALLBACKS :STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
 :STACK-ALLOCATABLE-VECTORS :STACK-ALLOCATABLE-CLOSURES :RAW-INSTANCE-INIT-VOPS
 :UNWIND-TO-FRAME-AND-CALL-VOP :COMPARE-AND-SWAP-VOPS :LINKAGE-TABLE
 :C-STACK-IS-CONTROL-STACK :STACK-GROWS-DOWNWARD-NOT-UPWARD :GENCGC :LARGEFILE
 :SB-FUTEX :LINUX :ELF :UNIX :X86-64 :SB-CORE-COMPRESSION
 :SB-XREF-FOR-INTERNALS :SB-AFTER-XC-CORE :SB-THREAD)

uname -a:

Linux central 3.4.4-gentoo #1 SMP PREEMPT Thu Jun 28 10:23:12 CDT 2012 x86_64 Dual-Core AMD Opteron(tm) Processor 2216 AuthenticAMD GNU/Linux

Revision history for this message
Stas Boukarev (stassats) wrote :

Note that this only happens with dynamic-extent args:
(defun test (&rest args) (declare (dynamic-extent args)) (car args))
triggers it, while
(defun test (&rest args) (car args))
does not.

summary: - (&rest args) called with no args leads to memory fault
+ dynamic-extent &rest called with no args leads to memory fault
Changed in sbcl:
status: New → Triaged
importance: Undecided → High
tags: added: dynamic-extent
nixie (onixie)
Changed in sbcl:
status: Triaged → Confirmed
Stas Boukarev (stassats)
Changed in sbcl:
status: Confirmed → Triaged
Revision history for this message
nixie (onixie) wrote :

This bug is introduced by commit 373df66 for optimizing &REST arguments.

The (CAR ARGS) in #'TEST is source-transformed to
        (%REST-REF 0 ARGS #:REST-CONTEXT #:REST-COUNT) which might be (the optimized case) finally ir1-transformed to
        (%MORE-ARG #:REST-CONTEXT 0) for accessing the CAR of ARGS in more context.
The bad thing is %MORE-ARG can't check context boundary itself and %REST-REF doesn't help it either.

Unfortunately, more context won't be established if caller of #'TEST doesn't supply any rest arguments, see COPY-MORE-ARG.

This bug is just the case. %MORE-ARG accesses stack area which is not a more context at all; Any unexpected low level bits can be returned as the CAR of ARGS, including things not a lisp object.

The same reason bug also happens in NTH, ELT. try:

    (defun test (n &rest args)
          (nth n args))

    (loop for i from 0 to 1000
              collect (test i))

I'm not very familiar with the more context actually, so to ensure I don't have miss understanding. To fix the bug,
Is it ok to let %REST-ARGS to check the context boundary,
or 'd better extend %MORE-ARG to check the context boundary.
or 'd better change %MORE-ARG-CONTEXT to return (values NIL 0) if no context established?

Revision history for this message
Stas Boukarev (stassats) wrote :

Fixed in fa2e7181b3f21505a340ae25a5f41998f67665a8

Changed in sbcl:
status: Triaged → Fix Committed
Stas Boukarev (stassats)
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.