file-systems: Spawn a REPL only when interaction is possible.

Fixes <https://bugs.gnu.org/23697>.
Reported by Jan Nieuwenhuizen <janneke@gnu.org>.

* gnu/build/file-systems.scm (check-file-system): Call 'start-repl' only
if current-input-port passes 'isatty?'.
* gnu/services/shepherd.scm (shepherd-configuration-file): After
'for-each' expression, call 'redirect-port'.
* gnu/tests/base.scm (run-basic-test)["stdin is /dev/null"]: New test.
master
Ludovic Courtès 2018-12-18 14:51:56 +01:00
parent 65c8a04370
commit 6ea6e1476f
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
3 changed files with 32 additions and 4 deletions

View File

@ -535,10 +535,13 @@ were found."
(sleep 3)
(reboot))
('fatal-error
(format (current-error-port)
"File system check on ~a failed; spawning Bourne-like REPL~%"
(format (current-error-port) "File system check on ~a failed~%"
device)
(start-repl %bournish-language)))
;; Spawn a REPL only if someone would be able to interact with it.
(when (isatty? (current-input-port))
(format (current-error-port) "Spawning Bourne-like REPL.~%")
(start-repl %bournish-language))))
(format (current-error-port)
"No file system check procedure for ~a; skipping~%"
device)))

View File

@ -281,7 +281,17 @@ stored."
(start service)))
'#$(append-map shepherd-service-provision
(filter shepherd-service-auto-start?
services)))))))
services)))
;; Hang up stdin. At this point, we assume that 'start' methods
;; that required user interaction on the console (e.g.,
;; 'cryptsetup open' invocations, post-fsck emergency REPL) have
;; completed. User interaction becomes impossible after this
;; call; this avoids situations where services wrongfully lead
;; PID 1 to read from stdin (the console), which users may not
;; have access to (see <https://bugs.gnu.org/23697>).
(redirect-port (open-input-file "/dev/null")
(current-input-port))))))
(scheme-file "shepherd.conf" config)))

View File

@ -123,6 +123,21 @@ initialization step, such as entering a LUKS passphrase."
#f))))
marionette))
(test-eq "stdin is /dev/null"
'eof
;; Make sure services can no longer read from stdin once the
;; system has booted.
(marionette-eval
`(begin
(use-modules (gnu services herd))
(start 'user-processes)
((@@ (gnu services herd) eval-there)
'(let ((result (read (current-input-port))))
(if (eof-object? result)
'eof
result))))
marionette))
(test-assert "shell and user commands"
;; Is everything in $PATH?
(zero? (marionette-eval '(system "