sharplispers / ironclad

A cryptographic toolkit written in Common Lisp
BSD 3-Clause "New" or "Revised" License
166 stars 28 forks source link

/dev/urandom closed by save-lisp-and-die #45

Closed K1D77A closed 2 years ago

K1D77A commented 3 years ago

When (ironclad:random-bits ..) is evaluated within a lisp image that I have generated with save-lisp-and-die I get the following condition:

LUNA-SITE> (ironclad:random-bits 13)
  0: (ERROR SB-INT:CLOSED-SAVED-STREAM-ERROR :STREAM #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}>)
; Debugger entered on #<SB-INT:CLOSED-SAVED-STREAM-ERROR {10086C5E63}>
#<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}> was closed by SB-EXT:SAVE-LISP-AND-DIE
   [Condition of type SB-INT:CLOSED-SAVED-STREAM-ERROR]

Restarts:
 0: [RETRY] Retry SLY mREPL evaluation request.
 1: [*ABORT] Return to SLY's top level.
 2: [ABORT] abort thread (#<THREAD "sly-channel-1-mrepl-remote-1" RUNNING {10098EABC3}>)

Backtrace:
 0: (SB-DEBUG::TRACE-CALL #<SB-DEBUG::TRACE-INFO ERROR> #<FUNCTION ERROR> SB-INT:CLOSED-SAVED-STREAM-ERROR :STREAM #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}>)
 1: (SB-IMPL::CLOSED-FLAME-SAVED #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}>)
 2: (SB-IMPL::ANSI-STREAM-READ-N-BYTES #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}> #(0 0) 0 2 NIL)
 3: (SB-IMPL:ANSI-STREAM-READ-SEQUENCE #(0 0) #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}> 0 NIL)
 4: (READ-SEQUENCE #(0 0) #<SB-SYS:FD-STREAM for "file /dev/urandom" {1001B04DF3}> :START 0 :END NIL)
 5: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-THREAD::CALL-WITH-MUTEX))
 6: (SB-THREAD::CALL-WITH-MUTEX #<FUNCTION (FLET SB-THREAD::WITH-MUTEX-THUNK :IN IRONCLAD::PRNG-RANDOM-DATA) {7F5A7A215C1B}> #<SB-THREAD:MUTEX "Anonymous lock" owner: #<SB-THREAD:THREAD "sly-channel-1-mre..
 7: ((:METHOD IRONCLAD::PRNG-RANDOM-DATA (T IRONCLAD:OS-PRNG)) 2 #<unused argument>) [fast-method]
 8: (IRONCLAD:RANDOM-BITS 13 #<IRONCLAD:OS-PRNG {1001AE8323}>)
 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (IRONCLAD:RANDOM-BITS 13) #<NULL-LEXENV>)
10: (EVAL (IRONCLAD:RANDOM-BITS 13))
11: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 --more--

This is on an image that I have exported with save-lisp-and-die and is running on a remote vps. If I boot a fresh sbcl on that VPS, QL ironclad and run the same I have no issue.

glv2 commented 3 years ago

The stream for "/dev/urandom" gets opened the first time some random data is requested, for example with random-data, random-bits or strong-random. The error you get happens when using save-lisp-and-die in a session where some random data has already been requested from Ironclad, because save-lisp-and-die closes the stream, but in a strange way. Trying to read data from this closed stream throws a SB-INT:CLOSED-SAVED-STREAM-ERROR error, however calling open-stream-p on it returns T. Maybe that's a bug in SBCL, I'll ask the developers...

For the moment I can think of two workarounds:

  1. If that's possible in your case, use save-lisp-and-die in a session where no random data has been requested from Ironclad yet.
  2. Run (progn (close ironclad::*os-prng-stream*) (setf ironclad::*os-prng-stream* nil)) just before calling save-lisp-and-die.
glv2 commented 2 years ago

Using Ironclad >= 0.56 and SBCL >= 2.1.8 should solve the issue without the need for a workaround.

K1D77A commented 2 years ago

Thanks :+1: