Merge security/p3.1-shell-temp
ober
a352011e453a133ec441a13a9f16f41175a8a46c
--- a/src/jcode/core/sandbox.ss +++ b/src/jcode/core/sandbox.ss @@ -22,6 +22,7 @@ (import :std/misc/string :std/os/path + :std/os/aproc ;; P3.1: argv-style spawn replaces (system "cmd > tmp 2> tmp") :jcode/core/config :jcode/core/log) @@ -121,25 +122,10 @@ (def (process-run-capture command) ;; Minimal shell capture so we don't take a dep on the bash tool. ;; Returns (values stdout stderr exit-code). - (let ((tmp-out (format "/tmp/jcode-uname-~a-out" (real-time))) - (tmp-err (format "/tmp/jcode-uname-~a-err" (real-time)))) - (let ((rc (system (format "~a > ~a 2> ~a" command tmp-out tmp-err)))) - (let ((out (try (call-with-input-file tmp-out - (lambda (p) - (let loop ((acc "")) - (let ((line (get-line p))) - (if (eof-object? line) - acc - (loop (string-append acc line "\n"))))))) - (catch (e) ""))) - (err (try (call-with-input-file tmp-err - (lambda (p) - (let loop ((acc "")) - (let ((line (get-line p))) - (if (eof-object? line) - acc - (loop (string-append acc line "\n"))))))) - (catch (e) "")))) - (when (file-exists? tmp-out) (delete-file tmp-out)) - (when (file-exists? tmp-err) (delete-file tmp-err)) - (values out err rc))))) + ;; + ;; P3.1: was (system "~a > /tmp/jcode-uname-<real-time> 2> ..."), which + ;; (a) wrote to predictable, racy paths in /tmp (symlink attack window), + ;; (b) shelled out via (system) — fine for trusted callers, but the + ;; tmp-file pattern was the security-relevant part. aproc-run/status + ;; pipes stdout/stderr in memory, no temp files, no path race. + (aproc-run/status command)) --- a/src/jcode/core/secrets.ss +++ b/src/jcode/core/secrets.ss @@ -163,15 +163,21 @@ (else (display prompt (current-error-port)) (flush-output-port (current-error-port)) + ;; P3.1: restore terminal echo even if get-line raises out of the + ;; guard (e.g. Ctrl-C in some shells). Without unwind-protect a + ;; thrown signal between stty -echo and stty echo leaves the user's + ;; terminal silently invisible. (system "stty -echo 2>/dev/null") - (let ((line (guard (e (#t #f)) - (get-line (current-input-port))))) - (system "stty echo 2>/dev/null") - (newline (current-error-port)) - (cond - ((or (not line) (eof-object? line)) - (error 'secret-prompt-passphrase "no passphrase provided")) - (else (string-trim line)))))))) + ;; try/finally guarantees stty echo restoration; (jerboa core) already imported. + (try + (let ((line (guard (e (#t #f)) + (get-line (current-input-port))))) + (newline (current-error-port)) + (cond + ((or (not line) (eof-object? line)) + (error 'secret-prompt-passphrase "no passphrase provided")) + (else (string-trim line)))) + (finally (system "stty echo 2>/dev/null"))))))) ;;; ---- on-disk format ----