Reduce host-side privileged assembly surface

This commit is contained in:
2026-04-10 19:15:06 +02:00
parent 4936f1193b
commit 52808502ef
5 changed files with 133 additions and 88 deletions
+3
View File
@@ -298,6 +298,9 @@ Current progress:
- rootfs population helpers now run through the jailed helper path too
- image/installer/ISO assembly now records staged jail metadata and uses a
dedicated assembly privileged policy surface
- install-time storage layout application is now executed as a rendered
privileged helper script under that policy instead of many scattered host-side
privileged calls
- network is disabled by default in these jailed paths
- union assembly mounts are now much smaller and omit host `/etc` and `devfs`
- direct block-device `system install` is now an explicit opt-in under the
+33 -16
View File
@@ -1507,10 +1507,12 @@
(assembly-privileged-policy-path
(string-append staging-metadata-relative-root "/assembly-privileged-policy.scm"))
(rootfs-populate-metadata-path (string-append staging-metadata-relative-root "/rootfs-populate.scm"))
(storage-apply-metadata-path (string-append staging-metadata-relative-root "/storage-apply.scm"))
(rootfs-copy-metadata-path (string-append staging-metadata-relative-root "/rootfs-copy.scm"))
(store-copy-metadata-path (string-append staging-metadata-relative-root "/store-copy.scm"))
(assembly-privileged-policy-file (string-append rootfs assembly-privileged-policy-path))
(rootfs-populate-metadata-file (string-append rootfs rootfs-populate-metadata-path))
(storage-apply-metadata-temp-file (string-append build-root "/storage-apply.scm"))
(rootfs-copy-metadata-temp-file (string-append build-root "/rootfs-copy.scm"))
(store-copy-metadata-temp-file (string-append build-root "/store-copy.scm"))
(target-device #f)
@@ -1549,8 +1551,12 @@
(set! storage-plan
(assoc-ref (apply-freebsd-storage-layout effective-storage-layout
#:root-mount-point mnt-root
#:privileged-policy privileged-policy)
#:privileged-policy privileged-policy
#:metadata-file storage-apply-metadata-temp-file)
'plan))
(install-metadata-file-into-mounted-root privileged-policy
storage-apply-metadata-temp-file
(string-append mnt-root storage-apply-metadata-path))
(set! mounted-targets (freebsd-storage-plan-mount-targets storage-plan))
(let ((esp-entry (freebsd-storage-plan-partition-by-role storage-plan 'efi))
(root-entry (or (freebsd-storage-plan-partition-by-role storage-plan 'root)
@@ -1604,6 +1610,7 @@
(install-metadata-path . ,install-metadata-relative-path)
(assembly-privileged-policy-path . ,assembly-privileged-policy-path)
(rootfs-populate-metadata-path . ,rootfs-populate-metadata-path)
(storage-apply-metadata-path . ,storage-apply-metadata-path)
(rootfs-copy-metadata-path . ,rootfs-copy-metadata-path)
(store-copy-metadata-path . ,store-copy-metadata-path)
(closure-path . ,closure-path)
@@ -1618,22 +1625,32 @@
(store-layout-file . ,(assoc-ref closure 'store-layout-file))
(store-items . ,store-items)))
(lambda ()
(for-each (lambda (mount-target)
(run-assembly-privileged-shell-command
privileged-policy
'unmount-file-system
(string-append "umount "
(shell-quote mount-target)
" >/dev/null 2>&1 || true")))
mounted-targets)
(when target-md
(run-assembly-privileged-shell-command
(when (or (pair? mounted-targets) target-md)
(run-assembly-privileged-script
privileged-policy
'mdconfig-detach
(string-append "mdconfig -d -u "
(shell-quote (string-drop target-md 2))
" >/dev/null 2>&1 || true"))
(set! target-md #f))
"fruix-install-cleanup"
(string-append
"#!/bin/sh\n"
"set +e\n"
(string-concatenate
(map (lambda (mount-target)
(string-append "umount "
(shell-quote mount-target)
" >/dev/null 2>&1 || true\n"))
mounted-targets))
(if target-md
(string-append "mdconfig -d -u "
(shell-quote (string-drop target-md 2))
" >/dev/null 2>&1 || true\n")
""))
#:operations (delete-duplicates
(append (if (pair? mounted-targets)
'(unmount-file-system)
'())
(if target-md
'(mdconfig-detach)
'())))))
(set! target-md #f)
(when (file-exists? build-root)
(delete-file-recursively build-root))))))
+56 -72
View File
@@ -324,6 +324,12 @@
(mount-targets . ,(freebsd-storage-plan-mount-targets plan))
(partitions . ,(action-ref plan 'partitions '()))))
(define (storage-shell-quote text)
(string-append "'" (string-replace-all text "'" "'\"'\"'") "'"))
(define (render-shell-command argv)
(string-join (map storage-shell-quote argv) " "))
(define (render-add-partition-action entry)
(let* ((argv (append (list "gpart" "add" "-a" "1m")
(let ((size (action-ref entry 'size #f)))
@@ -333,7 +339,7 @@
(list "-t" (action-ref entry 'gpart-type #f)
"-l" (action-ref entry 'partition-label #f)
(action-ref entry 'device #f)))))
(string-join argv " ")))
(render-shell-command argv)))
(define (render-freebsd-storage-layout-plan plan)
(let ((actions (action-ref plan 'actions '())))
@@ -341,12 +347,15 @@
(map (lambda (entry)
(case (action-ref entry 'kind #f)
((destroy-device)
(format #f "gpart destroy -F ~a >/dev/null 2>&1 || true"
(action-ref entry 'device #f)))
(string-append
(render-shell-command
(list "gpart" "destroy" "-F" (action-ref entry 'device #f)))
" >/dev/null 2>&1 || true"))
((create-partition-table)
(format #f "gpart create -s ~a ~a"
(symbol->string (action-ref entry 'partition-table #f))
(action-ref entry 'device #f)))
(render-shell-command
(list "gpart" "create" "-s"
(symbol->string (action-ref entry 'partition-table #f))
(action-ref entry 'device #f))))
((add-partition)
(render-add-partition-action entry))
((format-file-system)
@@ -355,89 +364,64 @@
(label (action-ref entry 'file-system-label #f)))
(cond
((string=? format-name "msdosfs")
(format #f "newfs_msdos -L EFISYS ~a" partition-device))
(render-shell-command
(list "newfs_msdos" "-L" "EFISYS" partition-device)))
((string=? format-name "ufs")
(format #f "newfs -U -L ~a ~a" label partition-device))
(render-shell-command
(list "newfs" "-U" "-L" label partition-device)))
(else
(format #f "# unsupported filesystem format ~a on ~a" format-name partition-device)))))
((mkdir)
(format #f "mkdir -p ~a" (action-ref entry 'path #f)))
(render-shell-command
(list "mkdir" "-p" (action-ref entry 'path #f))))
((mount-file-system)
(format #f "mount -t ~a ~a ~a"
(action-ref entry 'format #f)
(action-ref entry 'partition-device #f)
(action-ref entry 'mount-target #f)))
(render-shell-command
(list "mount" "-t"
(action-ref entry 'format #f)
(action-ref entry 'partition-device #f)
(action-ref entry 'mount-target #f))))
(else
(format #f "# unknown storage action ~s" entry))))
actions)
"\n")))
(define (run-format-action entry privileged-policy)
(let ((format-name (action-ref entry 'format #f))
(partition-device (action-ref entry 'partition-device #f))
(label (action-ref entry 'file-system-label #f)))
(cond
((string=? format-name "msdosfs")
(run-assembly-privileged-command privileged-policy
'format-msdosfs
"newfs_msdos" "-L" "EFISYS" partition-device))
((string=? format-name "ufs")
(run-assembly-privileged-command privileged-policy
'format-ufs
"newfs" "-U" "-L" label partition-device))
(else
(error "unsupported filesystem format in FreeBSD storage backend" format-name entry)))))
(define (run-action entry privileged-policy)
(define (storage-action->assembly-operations entry)
(case (action-ref entry 'kind #f)
((destroy-device)
(run-assembly-privileged-shell-command
privileged-policy
'destroy-device
(string-append "gpart destroy -F "
(action-ref entry 'device #f)
" >/dev/null 2>&1 || true"))
#t)
((create-partition-table)
(run-assembly-privileged-command privileged-policy
'create-partition-table
"gpart" "create" "-s"
(symbol->string (action-ref entry 'partition-table #f))
(action-ref entry 'device #f)))
((add-partition)
(let* ((size (action-ref entry 'size #f))
(argv (append (list privileged-policy
'add-partition
"gpart" "add" "-a" "1m")
(if size
(list "-s" size)
'())
(list "-t" (action-ref entry 'gpart-type #f)
"-l" (action-ref entry 'partition-label #f)
(action-ref entry 'device #f)))))
(apply run-assembly-privileged-command argv)))
((destroy-device) '(destroy-device))
((create-partition-table) '(create-partition-table))
((add-partition) '(add-partition))
((format-file-system)
(run-format-action entry privileged-policy))
((mkdir)
(run-assembly-privileged-command privileged-policy
'create-mount-target
"mkdir" "-p" (action-ref entry 'path #f)))
((mount-file-system)
(run-assembly-privileged-command privileged-policy
'mount-file-system
"mount" "-t"
(action-ref entry 'format #f)
(action-ref entry 'partition-device #f)
(action-ref entry 'mount-target #f)))
(let ((format-name (action-ref entry 'format #f)))
(cond
((string=? format-name "msdosfs") '(format-msdosfs))
((string=? format-name "ufs") '(format-ufs))
(else
(error "unsupported filesystem format in FreeBSD storage backend" format-name entry)))))
((mkdir) '(create-mount-target))
((mount-file-system) '(mount-file-system))
(else
(error "unknown FreeBSD storage backend action" entry))))
(define (storage-plan-assembly-operations plan)
(delete-duplicates
(append-map storage-action->assembly-operations
(action-ref plan 'actions '()))))
(define (storage-plan-script plan)
(string-append "#!/bin/sh\n"
"set -eu\n"
(render-freebsd-storage-layout-plan plan)
"\n"))
(define* (apply-freebsd-storage-layout layout #:key (root-mount-point "/mnt")
(privileged-policy (default-assembly-privileged-policy)))
(privileged-policy (default-assembly-privileged-policy))
metadata-file)
(let ((plan (freebsd-storage-layout-plan layout #:root-mount-point root-mount-point)))
(for-each (lambda (entry)
(run-action entry privileged-policy))
(action-ref plan 'actions '()))
(run-assembly-privileged-script privileged-policy
"fruix-storage-layout-apply"
(storage-plan-script plan)
#:operations (storage-plan-assembly-operations plan)
#:metadata-file metadata-file)
`((plan . ,plan)
(disk-device . ,(action-ref plan 'disk-device #f))
(root-mount-point . ,(action-ref plan 'root-mount-point #f))
+40
View File
@@ -42,6 +42,7 @@
run-assembly-privileged-command
run-assembly-privileged-shell-command
assembly-privileged-command-output
run-assembly-privileged-script
store-reference-closure
copy-store-items-into-rootfs
copy-rootfs-for-image
@@ -404,6 +405,45 @@
" "
(command->shell-fragment program args))))
(define assembly-privileged-script-metadata-version "1")
(define* (assembly-privileged-script-metadata policy name operations script)
`((assembly-privileged-script-metadata-version . ,assembly-privileged-script-metadata-version)
(name . ,name)
(policy . ,policy)
(operations . ,operations)
(script . ,script)
(command . ,(string-append (assembly-privileged-policy-command-prefix policy)
" sh <script>"))))
(define* (run-assembly-privileged-script policy name script
#:key
(operations '())
metadata-file)
(for-each (lambda (operation)
(ensure-assembly-privileged-policy-allows-operation policy operation))
operations)
(let ((script-path (command-output "mktemp"
(string-append (getenv* "TMPDIR" "/tmp")
"/fruix-assembly-privileged.XXXXXX"))))
(dynamic-wind
(lambda ()
(write-file script-path script)
(chmod script-path #o555)
(when metadata-file
(mkdir-p (dirname metadata-file))
(write-file metadata-file
(object->string
(assembly-privileged-script-metadata policy name operations script)))
(chmod metadata-file #o644)))
(lambda ()
(run-command "sh" "-c"
(string-append (assembly-privileged-policy-command-prefix policy)
" sh "
(shell-quote script-path))))
(lambda ()
(delete-file-if-exists script-path)))))
(define (store-reference-closure roots)
(let ((seen (make-hash-table))
(result '()))
+1
View File
@@ -453,6 +453,7 @@ Common options:\n\
(install_metadata_path . ,(assoc-ref result 'install-metadata-path))
(assembly_privileged_policy_path . ,(assoc-ref result 'assembly-privileged-policy-path))
(rootfs_populate_metadata_path . ,(assoc-ref result 'rootfs-populate-metadata-path))
(storage_apply_metadata_path . ,(assoc-ref result 'storage-apply-metadata-path))
(rootfs_copy_metadata_path . ,(assoc-ref result 'rootfs-copy-metadata-path))
(store_copy_metadata_path . ,(assoc-ref result 'store-copy-metadata-path))
(freebsd_base_name . ,(freebsd-base-name base))