helper/bwrap: implement overlayfs builder
Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
2e3f6a4c51
commit
e2489059c1
@ -4,10 +4,20 @@ const (
|
|||||||
Tmpfs = iota
|
Tmpfs = iota
|
||||||
Dir
|
Dir
|
||||||
Symlink
|
Symlink
|
||||||
|
|
||||||
|
OverlaySrc
|
||||||
|
Overlay
|
||||||
|
TmpOverlay
|
||||||
|
ROOverlay
|
||||||
)
|
)
|
||||||
|
|
||||||
var awkwardArgs = [...]string{
|
var awkwardArgs = [...]string{
|
||||||
Tmpfs: "--tmpfs",
|
Tmpfs: "--tmpfs",
|
||||||
Dir: "--dir",
|
Dir: "--dir",
|
||||||
Symlink: "--symlink",
|
Symlink: "--symlink",
|
||||||
|
|
||||||
|
OverlaySrc: "--overlay-src",
|
||||||
|
Overlay: "--overlay",
|
||||||
|
TmpOverlay: "--tmp-overlay",
|
||||||
|
ROOverlay: "--ro-overlay",
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,8 @@ type Config struct {
|
|||||||
--userns FD Use this user namespace (cannot combine with --unshare-user)
|
--userns FD Use this user namespace (cannot combine with --unshare-user)
|
||||||
--userns2 FD After setup switch to this user namespace, only useful with --userns
|
--userns2 FD After setup switch to this user namespace, only useful with --userns
|
||||||
--pidns FD Use this pid namespace (as parent namespace if using --unshare-pid)
|
--pidns FD Use this pid namespace (as parent namespace if using --unshare-pid)
|
||||||
|
--bind-fd FD DEST Bind open directory or path fd on DEST
|
||||||
|
--ro-bind-fd FD DEST Bind open directory or path fd read-only on DEST
|
||||||
--exec-label LABEL Exec label for the sandbox
|
--exec-label LABEL Exec label for the sandbox
|
||||||
--file-label LABEL File label for temporary sandbox content
|
--file-label LABEL File label for temporary sandbox content
|
||||||
--file FD DEST Copy from FD to destination DEST
|
--file FD DEST Copy from FD to destination DEST
|
||||||
@ -178,6 +180,74 @@ func (t *TmpfsConfig) Append(args *[]string) {
|
|||||||
*args = append(*args, awkwardArgs[Tmpfs], t.Dir)
|
*args = append(*args, awkwardArgs[Tmpfs], t.Dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OverlayConfig struct {
|
||||||
|
/*
|
||||||
|
read files from SRC in the following overlay
|
||||||
|
(--overlay-src SRC)
|
||||||
|
*/
|
||||||
|
Src []string `json:"src,omitempty"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
mount overlayfs on DEST, with RWSRC as the host path for writes and
|
||||||
|
WORKDIR an empty directory on the same filesystem as RWSRC
|
||||||
|
(--overlay RWSRC WORKDIR DEST)
|
||||||
|
|
||||||
|
if nil, mount overlayfs on DEST, with writes going to an invisible tmpfs
|
||||||
|
(--tmp-overlay DEST)
|
||||||
|
|
||||||
|
if either strings are empty, mount overlayfs read-only on DEST
|
||||||
|
(--ro-overlay DEST)
|
||||||
|
*/
|
||||||
|
Persist *[2]string `json:"persist,omitempty"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
--overlay RWSRC WORKDIR DEST
|
||||||
|
|
||||||
|
--tmp-overlay DEST
|
||||||
|
|
||||||
|
--ro-overlay DEST
|
||||||
|
*/
|
||||||
|
Dest string `json:"dest"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OverlayConfig) Path() string {
|
||||||
|
return o.Dest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OverlayConfig) Len() int {
|
||||||
|
// (--tmp-overlay DEST) or (--ro-overlay DEST)
|
||||||
|
p := 2
|
||||||
|
// (--overlay RWSRC WORKDIR DEST)
|
||||||
|
if o.Persist != nil && o.Persist[0] != "" && o.Persist[1] != "" {
|
||||||
|
p = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
return p + len(o.Src)*2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OverlayConfig) Append(args *[]string) {
|
||||||
|
// --overlay-src SRC
|
||||||
|
for _, src := range o.Src {
|
||||||
|
*args = append(*args, awkwardArgs[OverlaySrc], src)
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.Persist != nil {
|
||||||
|
if o.Persist[0] != "" && o.Persist[1] != "" {
|
||||||
|
// --overlay RWSRC WORKDIR
|
||||||
|
*args = append(*args, awkwardArgs[Overlay], o.Persist[0], o.Persist[1])
|
||||||
|
} else {
|
||||||
|
// --ro-overlay
|
||||||
|
*args = append(*args, awkwardArgs[ROOverlay])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// --tmp-overlay
|
||||||
|
*args = append(*args, awkwardArgs[TmpOverlay])
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEST
|
||||||
|
*args = append(*args, o.Dest)
|
||||||
|
}
|
||||||
|
|
||||||
type SymlinkConfig [2]string
|
type SymlinkConfig [2]string
|
||||||
|
|
||||||
func (s SymlinkConfig) Path() string {
|
func (s SymlinkConfig) Path() string {
|
||||||
|
@ -96,6 +96,31 @@ func (c *Config) Tmpfs(dest string, size int, perm ...os.FileMode) *Config {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overlay mount overlayfs on DEST, with writes going to an invisible tmpfs
|
||||||
|
// (--tmp-overlay DEST)
|
||||||
|
func (c *Config) Overlay(dest string, src ...string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join mount overlayfs read-only on DEST
|
||||||
|
// (--ro-overlay DEST)
|
||||||
|
func (c *Config) Join(dest string, src ...string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest, Persist: new([2]string)})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist mount overlayfs on DEST, with RWSRC as the host path for writes and
|
||||||
|
// WORKDIR an empty directory on the same filesystem as RWSRC
|
||||||
|
// (--overlay RWSRC WORKDIR DEST)
|
||||||
|
func (c *Config) Persist(dest, rwsrc, workdir string, src ...string) *Config {
|
||||||
|
if rwsrc == "" || workdir == "" {
|
||||||
|
panic("persist called without required paths")
|
||||||
|
}
|
||||||
|
c.Filesystem = append(c.Filesystem, &OverlayConfig{Src: src, Dest: dest, Persist: &[2]string{rwsrc, workdir}})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// Mqueue mount new mqueue in sandbox
|
// Mqueue mount new mqueue in sandbox
|
||||||
// (--mqueue DEST)
|
// (--mqueue DEST)
|
||||||
func (c *Config) Mqueue(dest string) *Config {
|
func (c *Config) Mqueue(dest string) *Config {
|
||||||
|
@ -13,6 +13,25 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
conf *bwrap.Config
|
conf *bwrap.Config
|
||||||
want []string
|
want []string
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
name: "overlayfs",
|
||||||
|
conf: (new(bwrap.Config)).
|
||||||
|
Overlay("/etc", "/etc").
|
||||||
|
Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin").
|
||||||
|
Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix"),
|
||||||
|
want: []string{
|
||||||
|
"--unshare-all", "--unshare-user",
|
||||||
|
"--disable-userns", "--assert-userns-disabled",
|
||||||
|
// Overlay("/etc", "/etc")
|
||||||
|
"--overlay-src", "/etc", "--tmp-overlay", "/etc",
|
||||||
|
// Join("/.fortify/bin", "/bin", "/usr/bin", "/usr/local/bin")
|
||||||
|
"--overlay-src", "/bin", "--overlay-src", "/usr/bin",
|
||||||
|
"--overlay-src", "/usr/local/bin", "--ro-overlay", "/.fortify/bin",
|
||||||
|
// Persist("/nix", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/data/app/org.chromium.Chromium/nix")
|
||||||
|
"--overlay-src", "/data/app/org.chromium.Chromium/nix",
|
||||||
|
"--overlay", "/data/data/org.chromium.Chromium/overlay/rwsrc", "/data/data/org.chromium.Chromium/workdir", "/nix",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "xdg-dbus-proxy constraint sample",
|
name: "xdg-dbus-proxy constraint sample",
|
||||||
conf: (&bwrap.Config{
|
conf: (&bwrap.Config{
|
||||||
|
Loading…
Reference in New Issue
Block a user