(zilch nixpkgs): Attempt to limit Nix expression leakage

Change-Id: Ifab2c0e7784145b9f57ca2c3cb713a476a6a6964
This commit is contained in:
puck 2025-11-24 18:37:10 +00:00
parent bf1f5b0ed9
commit 8385c3ac9b
3 changed files with 58 additions and 5 deletions

View file

@ -22,6 +22,7 @@
(verbose #f #\v) (verbose #f #\v)
(source #t #\s) (source #t #\s)
(project #t #\p) (project #t #\p)
(trust-all #f #\T)
(print-build-logs #f #\L)) (print-build-logs #f #\L))
(list->vector (cdr (command-line))) (list->vector (cdr (command-line)))
print-help)) print-help))
@ -62,10 +63,25 @@
(zilch zexpr) (zilch zexpr)
(srfi 128) (srfi 146) (srfi 152)) (srfi 128) (srfi 146) (srfi 152))
(when (assoc 'trust-all options) (nixpkgs-eval-allow-all))
(define source (and (assoc 'source options) (cdr (assoc 'source options)))) (define source (and (assoc 'source options) (cdr (assoc 'source options))))
(when source (nixpkgs-eval-allow-path source))
(define config-path (if (assoc 'config-file options) (cdr (assoc 'config-file options)) "zilch.scm")) (define config-path (if (assoc 'config-file options) (cdr (assoc 'config-file options)) "zilch.scm"))
; This is fine, canonicalisation is done without influence of the FS.
(nixpkgs-eval-allow-path (string-append config-path "/.."))
(define (allow-source-paths config)
(when (ninja-build-config-override-source-path config)
(nixpkgs-eval-allow-path (ninja-build-config-override-source-path)))
(for-each
(lambda (rewrite)
(allow-source-paths (cdr rewrite)))
(ninja-build-config-rewrites config)))
(define config (parse-ninja-config config-path (string=? (car args) "build")`(override-source: ,(and source (vfs-from-directory source)) ,@(call-with-input-file config-path read)))) (define config (parse-ninja-config config-path (string=? (car args) "build")`(override-source: ,(and source (vfs-from-directory source)) ,@(call-with-input-file config-path read))))
(allow-source-paths config)
(when (and (ninja-build-config-depfile-path config) (file-exists? (ninja-build-config-depfile-path config))) (when (and (ninja-build-config-depfile-path config) (file-exists? (ninja-build-config-depfile-path config)))
(set-ninja-build-config-depfile! config (alist->mapping (make-default-comparator) (call-with-input-file (ninja-build-config-depfile-path config) read)))) (set-ninja-build-config-depfile! config (alist->mapping (make-default-comparator) (call-with-input-file (ninja-build-config-depfile-path config) read))))

View file

@ -5,12 +5,42 @@
(zilch magic) (zilch nix drv) (zilch nix hash) (zilch magic) (zilch nix drv) (zilch nix hash)
(zilch nix path) (zilch zexpr) (zilch nix path) (zilch zexpr)
(srfi 18) (srfi 128) (srfi 146) (srfi 152) (srfi 18) (srfi 128) (srfi 146) (srfi 152)
(chicken format) (chicken process) (chicken format) (chicken process) (chicken pathname)
(chicken process-context)
json) json)
(export nix-prefetch-url nixpkgs nixpkgs-eval (export nix-prefetch-url nixpkgs nixpkgs-eval
nix-eval environment-for-derivation) nix-eval environment-for-derivation
nixpkgs-eval-allow-all nixpkgs-eval-allow-path)
(begin (begin
(define trusted-paths '())
(define (normalize-path path)
(if (string-prefix? "/" path)
path
(normalize-pathname (string-append (current-directory) "/" path) 'unix)))
;; Add a path to the list of trusted paths for Nix evaluations.
;; Paths will be normalized to be absolute, relative to the CWD.
;; This does not check symlinks, or the existence of any path component.
(define (nixpkgs-eval-allow-path path)
(when (and path trusted-paths)
(set! trusted-paths (cons (normalize-path path) trusted-paths))))
;; Don't restrict Nix evaluations.
(define (nixpkgs-eval-allow-all)
(set! trusted-paths #f))
; Append ">={path}" to the NIX_PATH for each argument.
; This is a hack as this is invalid channel syntax, e.g. `<<>` is invalid.
(define (nixpkgs-eval-trust-arguments)
(if trusted-paths
(let loop ((out '("--option" "restrict-eval" "true")) (args trusted-paths))
(if (null? args)
out
(loop (cons "-I" (cons (string-append ">=" (car args)) out)) (cdr args))))
'()))
(define (run-stderr-thread prefix port) (define (run-stderr-thread prefix port)
(define line (read-line port)) (define line (read-line port))
(if (eof-object? line) (if (eof-object? line)
@ -20,7 +50,7 @@
(run-stderr-thread prefix port)))) (run-stderr-thread prefix port))))
(define (read-from-nixpkgs path) (define (read-from-nixpkgs path)
(define-values (stdout stdin pid stderr) (process* "nix-instantiate" `("--argstr" "path" ,path "-E" "{path}: let nixpkgs = import <nixpkgs> {}; in nixpkgs.${path}.out"))) (define-values (stdout stdin pid stderr) (process* "nix-instantiate" `(,@(nixpkgs-eval-trust-arguments) "--argstr" "path" ,path "-E" "{path}: let nixpkgs = import <nixpkgs> {}; in nixpkgs.${path}.out")))
(define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append "nixpkgs." path) stderr)) "read-from-nixpkgs stderr passthrough"))) (define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append "nixpkgs." path) stderr)) "read-from-nixpkgs stderr passthrough")))
(close-port stdin) (close-port stdin)
(define drvpath (read-line stdout)) (define drvpath (read-line stdout))
@ -29,7 +59,7 @@
drvpath) drvpath)
(define (read-from-nixpkgs-raw path) (define (read-from-nixpkgs-raw path)
(define-values (stdout stdin pid stderr) (process* "nix-instantiate" `("-E" ,(string-append "with import <nixpkgs> {}; (" path ")")))) (define-values (stdout stdin pid stderr) (process* "nix-instantiate" `(,@(nixpkgs-eval-trust-arguments) "-E" ,(string-append "with import <nixpkgs> {}; (" path ")"))))
(define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append path) stderr)) "read-from-nixpkgs-raw stderr passthrough"))) (define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append path) stderr)) "read-from-nixpkgs-raw stderr passthrough")))
(close-port stdin) (close-port stdin)
(define drvpath (read-line stdout)) (define drvpath (read-line stdout))
@ -42,7 +72,7 @@
drvpath) drvpath)
(define (read-from-eval code) (define (read-from-eval code)
(define-values (stdout stdin pid stderr) (process* "nix-instantiate" `("--json" "--eval" "--strict" "--read-write-mode" "-E" ,code))) (define-values (stdout stdin pid stderr) (process* "nix-instantiate" `(,@(nixpkgs-eval-trust-arguments) "--json" "--eval" "--strict" "--read-write-mode" "-E" ,code)))
(define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append "eval `" code "`") stderr)) "read-from-eval stderr passthrough"))) (define thread (thread-start! (make-thread (lambda () (run-stderr-thread (string-append "eval `" code "`") stderr)) "read-from-eval stderr passthrough")))
(close-port stdin) (close-port stdin)
(define output (json-read stdout)) (define output (json-read stdout))

View file

@ -65,6 +65,13 @@ written. See the documentation at https://puck.moe/zilch/docs/.
*--verbose*:: *--verbose*::
Increase the verbosity configured in the Nix daemon. Increase the verbosity configured in the Nix daemon.
*-T*::
*--trust-all*::
By default, Nix expressions can only access the paths in NIX_PATH,
plus the source directories and the directory of the configuration.
Setting this flag drops this restriction, at the cost of Nix
expressions being able to escape the Nix sandbox easier.
*-L*:: *-L*::
*--print-build-logs*:: *--print-build-logs*::
Print derivation logs as they come in. Print derivation logs as they come in.