diff options
| author | Reepca Russelstein <reepca@russelstein.xyz> | 2025-07-24 17:35:37 -0500 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2025-09-01 16:13:11 +0200 |
| commit | 2a333541e8f1907ae0bc80cf500a99567ca46d08 (patch) | |
| tree | 57fd3e86b5a8b802b8a75baad5d98feaf4ecbb58 | |
| parent | 43bb79fc29e7f4f2ea06be138df195609b11ea97 (diff) | |
perform-download: Ensure reading never evaluates code.
Since this is used to implement the "download" and "git-download" builtins,
which are run outside of any chroot, this is trusted code with respect to the
user-supplied strings it reads.
* guix/scripts/perform-download.scm (read/safe): new procedure.
(perform-download, perform-git-download): use it.
(guix-perform-download): explicitly set 'read-eval?' to #f and
'read-hash-procedures' to '(). #f is the default value of 'read-eval?' on
startup, but set it anyway to be certain.
Change-Id: I93cb8e32607a6f9a559a26c1cbd6b88212ead884
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
| -rw-r--r-- | guix/scripts/perform-download.scm | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/guix/scripts/perform-download.scm b/guix/scripts/perform-download.scm index 5079d0ea71..64e4336c96 100644 --- a/guix/scripts/perform-download.scm +++ b/guix/scripts/perform-download.scm @@ -43,6 +43,11 @@ (let ((module (make-fresh-user-module))) (module-use! module (resolve-interface '(guix base32))) module)) +(define* (read/safe #:optional (port (current-input-port))) + (with-fluids ((read-eval? #f)) + (parameterize ((read-hash-procedures '())) + (read port)))) + (define* (perform-download drv output #:key print-build-trace?) @@ -60,7 +65,7 @@ Note: OUTPUT may differ from the 'out' value of DRV, notably for 'bmCheck' or (unless url (leave (G_ "~a: missing URL~%") (derivation-file-name drv))) - (let* ((url (call-with-input-string url read)) + (let* ((url (call-with-input-string url read/safe)) (drv-output (assoc-ref (derivation-outputs drv) "out")) (algo (derivation-output-hash-algo drv-output)) (hash (derivation-output-hash drv-output))) @@ -68,21 +73,21 @@ Note: OUTPUT may differ from the 'out' value of DRV, notably for 'bmCheck' or (when (parameterize ((%download-methods (and download-methods (call-with-input-string download-methods - read)))) + read/safe)))) (url-fetch url output #:print-build-trace? print-build-trace? #:mirrors (if mirrors - (call-with-input-file mirrors read) + (call-with-input-file mirrors read/safe) '()) #:content-addressed-mirrors (if content-addressed-mirrors (call-with-input-file content-addressed-mirrors (lambda (port) - (eval (read port) %user-module))) + (eval (read/safe port) %user-module))) '()) #:disarchive-mirrors (if disarchive-mirrors - (call-with-input-file disarchive-mirrors read) + (call-with-input-file disarchive-mirrors read/safe) '()) #:hashes `((,algo . ,hash)) @@ -108,9 +113,9 @@ Note: OUTPUT may differ from the 'out' value of DRV, notably for 'bmCheck' or (unless commit (leave (G_ "~a: missing Git commit~%") (derivation-file-name drv))) - (let* ((url (call-with-input-string url read)) + (let* ((url (call-with-input-string url read/safe)) (recursive? (and recursive? - (call-with-input-string recursive? read))) + (call-with-input-string recursive? read/safe))) (drv-output (assoc-ref (derivation-outputs drv) "out")) (algo (derivation-output-hash-algo drv-output)) (hash (derivation-output-hash drv-output))) @@ -123,7 +128,7 @@ Note: OUTPUT may differ from the 'out' value of DRV, notably for 'bmCheck' or (parameterize ((%download-methods (and download-methods (call-with-input-string download-methods - read)))) + read/safe)))) ;; Note: When doing a '--check' build, DRV-OUTPUT and OUTPUT are ;; different, hence the #:item argument below. (git-fetch-with-fallback url commit output @@ -153,6 +158,12 @@ Note: OUTPUT may differ from the 'out' value of DRV, notably for 'bmCheck' or (#f #f) (str (string-contains str "print-extended-build-trace=1")))) + ;; We read untrusted input, best to be sure this is #f! + (fluid-set! read-eval? #f) + ;; ... and out of an abundance of caution, remove the ability to use '#.' + ;; constructs entirely + (read-hash-procedures '()) + ;; This program must be invoked by guix-daemon under an unprivileged UID to ;; prevent things downloading from 'file:///etc/shadow' or arbitrary code ;; execution via the content-addressed mirror procedures. (That means we |
