From 289e95280c14b449f635f48f13c8c0417824237d Mon Sep 17 00:00:00 2001 From: w6vvn Date: Tue, 9 Sep 2025 15:35:36 -0700 Subject: [PATCH] secure ed, a little bit. --- palps.rkt | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/palps.rkt b/palps.rkt index fd712c1..cf06851 100755 --- a/palps.rkt +++ b/palps.rkt @@ -8,17 +8,27 @@ (or/c char-numeric? char-alphabetic? (curry char=? #\-)) (string->list call)))) +(define (our-make-temporary-file) + ;; when deployed as a systemd socket, this program is expected to be + ;; ran with PrivateTmp. however, in case this is not true, we still + ;; make our own directory. "red", the restricted version of "ed", + ;; has no facility for getting outside of the directory we start it + ;; in. + (make-temporary-file "red.~a" #:base-dir (make-temporary-directory))) + ;; unfortunately, we cannot just exec red and let it take over the ;; I/O. ed, being the standard text editor, only works with standard ;; line endings, \n. telnet and BPQ, however, use \r\n. \r\n upsets ;; ed, the standard text editor. so we need to wrap the input and ;; output ports ourselves in order to provide this translation. -(define (ed) +(define (ed [path (our-make-temporary-file)]) (match-define (list stdout stdin pid stderr proc) - (process* "/usr/bin/red" - "-p*" - #:set-pwd? #t)) + (parameterize ([current-directory (path-only path)]) + (process* "/usr/bin/red" + "-p*" + (path->string (file-name-from-path path)) + #:set-pwd? #t))) (define buffer (make-bytes 128)) @@ -45,9 +55,12 @@ ;; either event may EOF, which means that ed has died. [(eof-object? evt-result) + ;; clean up (close-output-port stdin) (close-input-port stdout) (close-input-port stderr) - (proc 'kill)]))) + (proc 'kill) + + path]))) (loop))