fix: input redirect nofollow, history symlink protection, SIGWINCH
ober
d829def572f6d6367d9433774342b64951a56a2c
--- a/history.ss +++ b/history.ss @@ -602,22 +602,29 @@ (checked-file (check-untainted-file-path file))) (dynamic-wind (lambda () - (set! port (open-output-file (check-untainted-file-path checked-file) 'truncate))) + ;; History contains every command typed — paths, hostnames, + ;; the occasional secret pasted in by accident. Open with + ;; O_NOFOLLOW so a symlink planted at $HISTFILE fails with + ;; ELOOP instead of writing through to its target, and set + ;; mode 0600 atomically at creation rather than via a racy + ;; chmod-after-open. + (let ((fd (ffi-open-raw checked-file + (bitwise-ior O_WRONLY O_CREAT O_TRUNC O_NOFOLLOW) + #o600))) + (unless (< fd 0) + (set! port (open-fd-output-port fd + (buffer-mode block) + (native-transcoder)))))) (lambda () - (for-each - (lambda (entry) - (display (history-entry-command entry) port) - (newline port)) - entries)) + (when port + (for-each + (lambda (entry) + (display (history-entry-command entry) port) + (newline port)) + entries))) (lambda () (when port - (close-output-port port)))) - ;; History contains every command typed — paths, hostnames, - ;; the occasional secret pasted in by accident. Other users - ;; on the box have no business reading it. We chmod even - ;; though umask is usually 0022, because users routinely - ;; unset umask and we don't want to inherit their choice. - (ffi-chmod checked-file #o600)))))))))) + (close-output-port port))))))))))))) ;; L-3: bound per-line length. read-line on a multi-GB single-line ;; file would attempt to allocate the whole thing. 64KiB is far past --- a/main.ss +++ b/main.ss @@ -627,9 +627,9 @@ ((string=? sig-name "CHLD") (job-update-status!) (job-notify!)) - ;; WINCH: terminal resize — update COLUMNS/LINES - ((string=? sig-name "WINCH") - (void)) ;; TODO: update terminal dimensions + ;; WINCH: terminal resize — refresh cached terminal dimensions + ((string=? sig-name "WINCH") + (set-terminal-columns! (detect-terminal-columns))) (else (void))) ;; Check trap table for this signal ;; Save and restore $? so trap doesn't affect main flow --- a/redirect.ss +++ b/redirect.ss @@ -229,7 +229,7 @@ ;; < file — input from file ((<) (let ((save (save-fd fd))) - (redirect-fd-to-file! fd target-str O_RDONLY 0) + (redirect-fd-to-file! fd target-str (apply-redir-flags env O_RDONLY) 0) ;; Create Gambit port for builtins (when (= fd 0) (current-input-port (open-input-file (check-untainted-file-path target-str)))) @@ -561,7 +561,7 @@ (error #f ": No such file or directory")) w)))))))) (case op - ((<) (redirect-fd-to-file! fd target-str O_RDONLY 0) + ((<) (redirect-fd-to-file! fd target-str (apply-redir-flags env O_RDONLY) 0) (when (= fd 0) (current-input-port (open-input-file (check-untainted-file-path target-str))))) ((>) (let* ((noclobber? (env-option? env "noclobber"))