Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions parenting-parent.el
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,11 @@ The Nix store, when present, is bound separately."
("LANG" . "C.UTF-8"))
"Environment set inside every `:sandbox' jail before pass-through.
An alist of (NAME . VALUE). The jail starts from an empty
environment (bwrap --clearenv); these are set with --setenv, then
HOME is pointed at the jail's tmpfs, and finally the caller's
`:environment' pass-through names are copied in from this Emacs's
environment. Rebind or extend this to change the baseline."
environment (bwrap --clearenv); HOME is set to a directory created
per child under the read-write socket-directory bind, these are set
with --setenv, and finally the caller's `:environment' pass-through
names are copied in from this Emacs's environment. Rebind or extend
this to change the baseline."
:type '(alist :key-type string :value-type string)
:group 'parenting)

Expand Down Expand Up @@ -243,7 +244,9 @@ SPEC keywords, all optional:

The returned list is suitable as a `:command-wrapper' prefix: bwrap,
a minimal read-only root, a private /tmp, /proc and /dev, the socket
and library binds, a cleared environment seeded from
and library binds, a HOME directory created per child under the
read-write socket-directory bind (removed with the socket directory
at shutdown), a cleared environment seeded from
`parenting-sandbox-default-environment' plus the pass-through names,
and network sharing only when asked."
(let* ((home (expand-file-name "home" socket-directory))
Expand Down Expand Up @@ -275,8 +278,16 @@ and network sharing only when asked."
;; Extra caller binds.
(parenting--sandbox-bind-args "--ro-bind" ro-binds)
(parenting--sandbox-bind-args "--bind" rw-binds)
;; A cleared environment: baseline, then a writable HOME on the
;; tmpfs, then the caller's pass-through names.
;; HOME: a directory bwrap creates in the jail under the read-write
;; socket-directory bind, so it exists and is writable before the
;; child starts (a daemon child writes savehist, recentf, its eln
;; cache and `user-emacs-directory' there). One per child; it is
;; removed with the socket directory at shutdown. This must come
;; after the socket-directory bind so the mount exists when the
;; directory is created inside it.
(list "--dir" home)
;; A cleared environment: baseline, then HOME, then the caller's
;; pass-through names.
(list "--clearenv")
(list "--setenv" "HOME" home)
(cl-mapcan (lambda (pair)
Expand Down
25 changes: 23 additions & 2 deletions test/parenting-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,23 @@ Single-argument bwrap flags: collects the one word after each FLAG."
(should (parenting-test--bind-p
args "--ro-bind" "/opt/parenting" "/opt/parenting"))
;; HOME is set (to a path under the socket directory).
(should (member "HOME" (parenting-test--flag-values args "--setenv")))))
(should (member "HOME" (parenting-test--flag-values args "--setenv")))
;; That HOME directory is created in the jail with --dir, inside
;; the socket-directory bind: after the bind (so the mount exists
;; when the directory is made) and before HOME is set to it.
(let* ((home (expand-file-name "home" "/run/sock-dir"))
(bind-pos (cl-position "/run/sock-dir" args :test #'equal))
(dir-pos (cl-position "--dir" args :test #'equal))
(setenv-home-pos (cl-loop for i from 0
for (flag name) on args
when (and (equal flag "--setenv")
(equal name "HOME"))
return i)))
(should (equal (list home) (parenting-test--flag-values args "--dir")))
(should bind-pos)
(should dir-pos)
(should setenv-home-pos)
(should (< bind-pos dir-pos setenv-home-pos)))))

(ert-deftest parenting-sandbox-wrapper-network-toggle ()
;; No network by default; --share-net only when the spec asks.
Expand Down Expand Up @@ -821,7 +837,12 @@ sandbox test skips rather than fails when it is unavailable."
(parenting-with-child (conn :sandbox '(:network nil) :timeout 60)
(should (equal 3 (parenting-eval conn '(+ 1 2))))
;; The child really is jailed: no host network was shared.
(should (equal "sandboxed" (parenting-eval conn '"sandboxed")))))
(should (equal "sandboxed" (parenting-eval conn '"sandboxed")))
;; HOME exists in the jail as a writable directory (created by
;; --dir under the socket-directory bind), so a daemon child can
;; write savehist, recentf and its eln cache there.
(should (parenting-eval conn '(file-directory-p (getenv "HOME"))))
(should (parenting-eval conn '(file-writable-p (getenv "HOME"))))))

(provide 'parenting-test)
;;; parenting-test.el ends here
Loading