sharplispers / ironclad

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

PRNG :OS does not work in multi-threaded applications on CCL #9

Closed wnortje closed 5 years ago

wnortje commented 5 years ago

CCL raises error Stream #<BASIC-FILE-BINARY-INPUT-STREAM ("/dev/urandom"/10 ISO-8859-1) #x30200241F31D> is private to #<PROCESS Anonymous thread(78) [Sleep] #x3020022B5D2D> when the OS prng is used in multi-threaded applications, eg inside Hunchentoot request handlers.

See https://ccl.clozure.com/docs/ccl.html#additional-keywords-for-open-and-make-socket

The code below shows the problem when run on CCL

(progn
  (setf ironclad:*PRNG* (ironclad:make-prng :os))
  (bordeaux-threads:make-thread
   (lambda ()
     (format t "Thread1: ~A~%" (ironclad:make-random-salt))
     (sleep 0.1)))

  (bordeaux-threads:make-thread
   (lambda ()
     (format t "Thread2: ~A~%" (ironclad:make-random-salt))
     (sleep 0.1))))

The fortuna prng does work.

Clozure Common Lisp Version 1.12-dev/v1.12-dev.1 (LinuxX8664) Kubuntu 18.04

luismbo commented 5 years ago

This seems like a CCL feature. Based on a quick inspection, it seems like the prngs aren't thread-safe so you shouldn't be sharing them across threads.

wnortje commented 5 years ago

Thanks.

This works

(progn
  (bordeaux-threads:make-thread
   (lambda ()
     (let* ((ironclad:*PRNG* (ironclad:make-prng :os)))
       (format t "Thread1: ~A~%" (ironclad:make-random-salt)))))

  (bordeaux-threads:make-thread
   (lambda ()
     (let ((ironclad:*PRNG* (ironclad:make-prng :os)))
       (format t "Thread2: ~A~%" (ironclad:make-random-salt))))))
eadmund commented 5 years ago

14 fixed this, I believe.