helper/bwrap: ordered filesystem args
The argument builder was written based on the incorrect assumption that bwrap arguments are unordered. The argument builder is replaced in this commit to correct that mistake. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
parent
a0db19b9ad
commit
2faf510146
|
@ -79,11 +79,9 @@ func (p *Proxy) Start(ready chan error, output io.Writer, sandbox bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bindTargetDedup := make([][2]string, 0, len(bindTarget))
|
|
||||||
for k := range bindTarget {
|
for k := range bindTarget {
|
||||||
bindTargetDedup = append(bindTargetDedup, [2]string{k, k})
|
bc.Bind(k, k, false, true)
|
||||||
}
|
}
|
||||||
bc.Bind = append(bc.Bind, bindTargetDedup...)
|
|
||||||
|
|
||||||
roBindTarget := make(map[string]struct{}, 2+1+len(proxyDeps))
|
roBindTarget := make(map[string]struct{}, 2+1+len(proxyDeps))
|
||||||
|
|
||||||
|
@ -103,11 +101,9 @@ func (p *Proxy) Start(ready chan error, output io.Writer, sandbox bool) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roBindTargetDedup := make([][2]string, 0, len(roBindTarget))
|
|
||||||
for k := range roBindTarget {
|
for k := range roBindTarget {
|
||||||
roBindTargetDedup = append(roBindTargetDedup, [2]string{k, k})
|
bc.Bind(k, k)
|
||||||
}
|
}
|
||||||
bc.ROBind = append(bc.ROBind, roBindTargetDedup...)
|
|
||||||
|
|
||||||
h = helper.MustNewBwrap(bc, p.seal, toolPath, argF)
|
h = helper.MustNewBwrap(bc, p.seal, toolPath, argF)
|
||||||
cmd = h.Unwrap()
|
cmd = h.Unwrap()
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
import "encoding/gob"
|
||||||
|
|
||||||
|
type Builder interface {
|
||||||
|
Len() int
|
||||||
|
Append(args *[]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSBuilder interface {
|
||||||
|
Path() string
|
||||||
|
Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
gob.Register(new(pairF))
|
||||||
|
gob.Register(new(stringF))
|
||||||
|
}
|
||||||
|
|
||||||
|
type pairF [3]string
|
||||||
|
|
||||||
|
func (p *pairF) Path() string {
|
||||||
|
return p[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pairF) Len() int {
|
||||||
|
return len(p) // compiler replaces this with 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pairF) Append(args *[]string) {
|
||||||
|
*args = append(*args, p[0], p[1], p[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringF [2]string
|
||||||
|
|
||||||
|
func (s stringF) Path() string {
|
||||||
|
return s[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stringF) Len() int {
|
||||||
|
return len(s) // compiler replaces this with 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stringF) Append(args *[]string) {
|
||||||
|
*args = append(*args, s[0], s[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args returns a slice of bwrap args corresponding to c.
|
||||||
|
func (c *Config) Args() (args []string) {
|
||||||
|
builders := []Builder{
|
||||||
|
c.boolArgs(),
|
||||||
|
c.intArgs(),
|
||||||
|
c.stringArgs(),
|
||||||
|
c.pairArgs(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy FSBuilder slice to builder slice
|
||||||
|
fb := make([]Builder, len(c.Filesystem)+1)
|
||||||
|
for i, f := range c.Filesystem {
|
||||||
|
fb[i] = f
|
||||||
|
}
|
||||||
|
fb[len(fb)-1] = c.Chmod
|
||||||
|
builders = append(builders, fb...)
|
||||||
|
|
||||||
|
// accumulate arg count
|
||||||
|
argc := 0
|
||||||
|
for _, b := range builders {
|
||||||
|
argc += b.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
args = make([]string, 0, argc)
|
||||||
|
for _, b := range builders {
|
||||||
|
b.Append(&args)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
const (
|
||||||
|
Tmpfs = iota
|
||||||
|
Dir
|
||||||
|
Symlink
|
||||||
|
)
|
||||||
|
|
||||||
|
var awkwardArgs = [...]string{
|
||||||
|
Tmpfs: "--tmpfs",
|
||||||
|
Dir: "--dir",
|
||||||
|
Symlink: "--symlink",
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
const (
|
||||||
|
UnshareAll = iota
|
||||||
|
UnshareUser
|
||||||
|
UnshareIPC
|
||||||
|
UnsharePID
|
||||||
|
UnshareNet
|
||||||
|
UnshareUTS
|
||||||
|
UnshareCGroup
|
||||||
|
ShareNet
|
||||||
|
|
||||||
|
UserNS
|
||||||
|
Clearenv
|
||||||
|
|
||||||
|
NewSession
|
||||||
|
DieWithParent
|
||||||
|
AsInit
|
||||||
|
)
|
||||||
|
|
||||||
|
var boolArgs = [...][]string{
|
||||||
|
UnshareAll: {"--unshare-all", "--unshare-user"},
|
||||||
|
UnshareUser: {"--unshare-user"},
|
||||||
|
UnshareIPC: {"--unshare-ipc"},
|
||||||
|
UnsharePID: {"--unshare-pid"},
|
||||||
|
UnshareNet: {"--unshare-net"},
|
||||||
|
UnshareUTS: {"--unshare-uts"},
|
||||||
|
UnshareCGroup: {"--unshare-cgroup"},
|
||||||
|
ShareNet: {"--share-net"},
|
||||||
|
|
||||||
|
UserNS: {"--disable-userns", "--assert-userns-disabled"},
|
||||||
|
Clearenv: {"--clearenv"},
|
||||||
|
|
||||||
|
NewSession: {"--new-session"},
|
||||||
|
DieWithParent: {"--die-with-parent"},
|
||||||
|
AsInit: {"--as-pid-1"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) boolArgs() Builder {
|
||||||
|
b := boolArg{
|
||||||
|
UserNS: !c.UserNS,
|
||||||
|
Clearenv: c.Clearenv,
|
||||||
|
|
||||||
|
NewSession: c.NewSession,
|
||||||
|
DieWithParent: c.DieWithParent,
|
||||||
|
AsInit: c.AsInit,
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Unshare == nil {
|
||||||
|
b[UnshareAll] = true
|
||||||
|
b[ShareNet] = c.Net
|
||||||
|
} else {
|
||||||
|
b[UnshareUser] = c.Unshare.User
|
||||||
|
b[UnshareIPC] = c.Unshare.IPC
|
||||||
|
b[UnsharePID] = c.Unshare.PID
|
||||||
|
b[UnshareNet] = c.Unshare.Net
|
||||||
|
b[UnshareUTS] = c.Unshare.UTS
|
||||||
|
b[UnshareCGroup] = c.Unshare.CGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
|
type boolArg [len(boolArgs)]bool
|
||||||
|
|
||||||
|
func (b *boolArg) Len() (l int) {
|
||||||
|
for i, v := range b {
|
||||||
|
if v {
|
||||||
|
l += len(boolArgs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *boolArg) Append(args *[]string) {
|
||||||
|
for i, v := range b {
|
||||||
|
if v {
|
||||||
|
*args = append(*args, boolArgs[i]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
const (
|
||||||
|
UID = iota
|
||||||
|
GID
|
||||||
|
Perms
|
||||||
|
Size
|
||||||
|
)
|
||||||
|
|
||||||
|
var intArgs = [...]string{
|
||||||
|
UID: "--uid",
|
||||||
|
GID: "--gid",
|
||||||
|
Perms: "--perms",
|
||||||
|
Size: "--size",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) intArgs() Builder {
|
||||||
|
// Arg types:
|
||||||
|
// Perms
|
||||||
|
// are handled by the sequential builder
|
||||||
|
|
||||||
|
return &intArg{
|
||||||
|
UID: c.UID,
|
||||||
|
GID: c.GID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type intArg [len(intArgs)]*int
|
||||||
|
|
||||||
|
func (n *intArg) Len() (l int) {
|
||||||
|
for _, v := range n {
|
||||||
|
if v != nil {
|
||||||
|
l += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *intArg) Append(args *[]string) {
|
||||||
|
for i, v := range n {
|
||||||
|
if v != nil {
|
||||||
|
*args = append(*args, intArgs[i], strconv.Itoa(*v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
const (
|
||||||
|
SetEnv = iota
|
||||||
|
|
||||||
|
Bind
|
||||||
|
BindTry
|
||||||
|
DevBind
|
||||||
|
DevBindTry
|
||||||
|
ROBind
|
||||||
|
ROBindTry
|
||||||
|
|
||||||
|
Chmod
|
||||||
|
)
|
||||||
|
|
||||||
|
var pairArgs = [...]string{
|
||||||
|
SetEnv: "--setenv",
|
||||||
|
|
||||||
|
Bind: "--bind",
|
||||||
|
BindTry: "--bind-try",
|
||||||
|
DevBind: "--dev-bind",
|
||||||
|
DevBindTry: "--dev-bind-try",
|
||||||
|
ROBind: "--ro-bind",
|
||||||
|
ROBindTry: "--ro-bind-try",
|
||||||
|
|
||||||
|
Chmod: "--chmod",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) pairArgs() Builder {
|
||||||
|
var n pairArg
|
||||||
|
n[SetEnv] = make([][2]string, 0, len(c.SetEnv))
|
||||||
|
for k, v := range c.SetEnv {
|
||||||
|
n[SetEnv] = append(n[SetEnv], [2]string{k, v})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg types:
|
||||||
|
// Bind
|
||||||
|
// BindTry
|
||||||
|
// DevBind
|
||||||
|
// DevBindTry
|
||||||
|
// ROBind
|
||||||
|
// ROBindTry
|
||||||
|
// Chmod
|
||||||
|
// are handled by the sequential builder
|
||||||
|
|
||||||
|
return &n
|
||||||
|
}
|
||||||
|
|
||||||
|
type pairArg [len(pairArgs)][][2]string
|
||||||
|
|
||||||
|
func (p *pairArg) Len() (l int) {
|
||||||
|
for _, v := range p {
|
||||||
|
l += len(v) * 3
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pairArg) Append(args *[]string) {
|
||||||
|
for i, arg := range p {
|
||||||
|
for _, v := range arg {
|
||||||
|
*args = append(*args, pairArgs[i], v[0], v[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
const (
|
||||||
|
Hostname = iota
|
||||||
|
Chdir
|
||||||
|
UnsetEnv
|
||||||
|
LockFile
|
||||||
|
|
||||||
|
RemountRO
|
||||||
|
Procfs
|
||||||
|
DevTmpfs
|
||||||
|
Mqueue
|
||||||
|
)
|
||||||
|
|
||||||
|
var stringArgs = [...]string{
|
||||||
|
Hostname: "--hostname",
|
||||||
|
Chdir: "--chdir",
|
||||||
|
UnsetEnv: "--unsetenv",
|
||||||
|
LockFile: "--lock-file",
|
||||||
|
|
||||||
|
RemountRO: "--remount-ro",
|
||||||
|
Procfs: "--proc",
|
||||||
|
DevTmpfs: "--dev",
|
||||||
|
Mqueue: "--mqueue",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) stringArgs() Builder {
|
||||||
|
n := stringArg{
|
||||||
|
UnsetEnv: c.UnsetEnv,
|
||||||
|
LockFile: c.LockFile,
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Hostname != "" {
|
||||||
|
n[Hostname] = []string{c.Hostname}
|
||||||
|
}
|
||||||
|
if c.Chdir != "" {
|
||||||
|
n[Chdir] = []string{c.Chdir}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arg types:
|
||||||
|
// RemountRO
|
||||||
|
// Procfs
|
||||||
|
// DevTmpfs
|
||||||
|
// Mqueue
|
||||||
|
// are handled by the sequential builder
|
||||||
|
|
||||||
|
return &n
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringArg [len(stringArgs)][]string
|
||||||
|
|
||||||
|
func (s *stringArg) Len() (l int) {
|
||||||
|
for _, arg := range s {
|
||||||
|
l += len(arg) * 2
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringArg) Append(args *[]string) {
|
||||||
|
for i, arg := range s {
|
||||||
|
for _, v := range arg {
|
||||||
|
*args = append(*args, stringArgs[i], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,64 +0,0 @@
|
||||||
package bwrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
UnshareAll = iota
|
|
||||||
UnshareUser
|
|
||||||
UnshareIPC
|
|
||||||
UnsharePID
|
|
||||||
UnshareNet
|
|
||||||
UnshareUTS
|
|
||||||
UnshareCGroup
|
|
||||||
ShareNet
|
|
||||||
|
|
||||||
UserNS
|
|
||||||
Clearenv
|
|
||||||
|
|
||||||
NewSession
|
|
||||||
DieWithParent
|
|
||||||
AsInit
|
|
||||||
|
|
||||||
boolC
|
|
||||||
)
|
|
||||||
|
|
||||||
var boolArgs = func() (b [boolC][]string) {
|
|
||||||
b[UnshareAll] = []string{"--unshare-all", "--unshare-user"}
|
|
||||||
b[UnshareUser] = []string{"--unshare-user"}
|
|
||||||
b[UnshareIPC] = []string{"--unshare-ipc"}
|
|
||||||
b[UnsharePID] = []string{"--unshare-pid"}
|
|
||||||
b[UnshareNet] = []string{"--unshare-net"}
|
|
||||||
b[UnshareUTS] = []string{"--unshare-uts"}
|
|
||||||
b[UnshareCGroup] = []string{"--unshare-cgroup"}
|
|
||||||
b[ShareNet] = []string{"--share-net"}
|
|
||||||
|
|
||||||
b[UserNS] = []string{"--disable-userns", "--assert-userns-disabled"}
|
|
||||||
b[Clearenv] = []string{"--clearenv"}
|
|
||||||
|
|
||||||
b[NewSession] = []string{"--new-session"}
|
|
||||||
b[DieWithParent] = []string{"--die-with-parent"}
|
|
||||||
b[AsInit] = []string{"--as-pid-1"}
|
|
||||||
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
func (c *Config) boolArgs() (b [boolC]bool) {
|
|
||||||
if c.Unshare == nil {
|
|
||||||
b[UnshareAll] = true
|
|
||||||
b[ShareNet] = c.Net
|
|
||||||
} else {
|
|
||||||
b[UnshareUser] = c.Unshare.User
|
|
||||||
b[UnshareIPC] = c.Unshare.IPC
|
|
||||||
b[UnsharePID] = c.Unshare.PID
|
|
||||||
b[UnshareNet] = c.Unshare.Net
|
|
||||||
b[UnshareUTS] = c.Unshare.UTS
|
|
||||||
b[UnshareCGroup] = c.Unshare.CGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
b[UserNS] = !c.UserNS
|
|
||||||
b[Clearenv] = c.Clearenv
|
|
||||||
|
|
||||||
b[NewSession] = c.NewSession
|
|
||||||
b[DieWithParent] = c.DieWithParent
|
|
||||||
b[AsInit] = c.AsInit
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -5,75 +5,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Config) Args() (args []string) {
|
|
||||||
b := c.boolArgs()
|
|
||||||
n := c.intArgs()
|
|
||||||
g := c.interfaceArgs()
|
|
||||||
s := c.stringArgs()
|
|
||||||
p := c.pairArgs()
|
|
||||||
|
|
||||||
argc := 0
|
|
||||||
for i, arg := range b {
|
|
||||||
if arg {
|
|
||||||
argc += len(boolArgs[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, arg := range n {
|
|
||||||
if arg != nil {
|
|
||||||
argc += 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, arg := range g {
|
|
||||||
argc += len(arg) * 3
|
|
||||||
}
|
|
||||||
for _, arg := range s {
|
|
||||||
argc += len(arg) * 2
|
|
||||||
}
|
|
||||||
for _, arg := range p {
|
|
||||||
argc += len(arg) * 3
|
|
||||||
}
|
|
||||||
|
|
||||||
args = make([]string, 0, argc)
|
|
||||||
for i, arg := range b {
|
|
||||||
if arg {
|
|
||||||
args = append(args, boolArgs[i]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range n {
|
|
||||||
if arg != nil {
|
|
||||||
args = append(args, intArgs[i], strconv.Itoa(*arg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range g {
|
|
||||||
for _, v := range arg {
|
|
||||||
if v.Later() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args = append(args, v.Value(interfaceArgs[i])...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range s {
|
|
||||||
for _, v := range arg {
|
|
||||||
args = append(args, stringArgs[i], v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range p {
|
|
||||||
for _, v := range arg {
|
|
||||||
args = append(args, pairArgs[i], v[0], v[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, arg := range g {
|
|
||||||
for _, v := range arg {
|
|
||||||
if !v.Later() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args = append(args, v.Value(interfaceArgs[i])...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// unshare every namespace we support by default if nil
|
// unshare every namespace we support by default if nil
|
||||||
// (--unshare-all)
|
// (--unshare-all)
|
||||||
|
@ -114,53 +45,12 @@ type Config struct {
|
||||||
// (--lock-file DEST)
|
// (--lock-file DEST)
|
||||||
LockFile []string `json:"lock_file,omitempty"`
|
LockFile []string `json:"lock_file,omitempty"`
|
||||||
|
|
||||||
// bind mount host path on sandbox
|
// ordered filesystem args
|
||||||
// (--bind SRC DEST)
|
Filesystem []FSBuilder
|
||||||
Bind [][2]string `json:"bind,omitempty"`
|
|
||||||
// equal to Bind but ignores non-existent host path
|
|
||||||
// (--bind-try SRC DEST)
|
|
||||||
BindTry [][2]string `json:"bind_try,omitempty"`
|
|
||||||
|
|
||||||
// bind mount host path on sandbox, allowing device access
|
|
||||||
// (--dev-bind SRC DEST)
|
|
||||||
DevBind [][2]string `json:"dev_bind,omitempty"`
|
|
||||||
// equal to DevBind but ignores non-existent host path
|
|
||||||
// (--dev-bind-try SRC DEST)
|
|
||||||
DevBindTry [][2]string `json:"dev_bind_try,omitempty"`
|
|
||||||
|
|
||||||
// bind mount host path readonly on sandbox
|
|
||||||
// (--ro-bind SRC DEST)
|
|
||||||
ROBind [][2]string `json:"ro_bind,omitempty"`
|
|
||||||
// equal to ROBind but ignores non-existent host path
|
|
||||||
// (--ro-bind-try SRC DEST)
|
|
||||||
ROBindTry [][2]string `json:"ro_bind_try,omitempty"`
|
|
||||||
|
|
||||||
// remount path as readonly; does not recursively remount
|
|
||||||
// (--remount-ro DEST)
|
|
||||||
RemountRO []string `json:"remount_ro,omitempty"`
|
|
||||||
|
|
||||||
// mount new procfs in sandbox
|
|
||||||
// (--proc DEST)
|
|
||||||
Procfs []string `json:"proc,omitempty"`
|
|
||||||
// mount new dev in sandbox
|
|
||||||
// (--dev DEST)
|
|
||||||
DevTmpfs []string `json:"dev,omitempty"`
|
|
||||||
// mount new tmpfs in sandbox
|
|
||||||
// (--tmpfs DEST)
|
|
||||||
Tmpfs []PermConfig[TmpfsConfig] `json:"tmpfs,omitempty"`
|
|
||||||
// mount new mqueue in sandbox
|
|
||||||
// (--mqueue DEST)
|
|
||||||
Mqueue []string `json:"mqueue,omitempty"`
|
|
||||||
// create dir in sandbox
|
|
||||||
// (--dir DEST)
|
|
||||||
Dir []PermConfig[string] `json:"dir,omitempty"`
|
|
||||||
// create symlink within sandbox
|
|
||||||
// (--symlink SRC DEST)
|
|
||||||
Symlink []PermConfig[[2]string] `json:"symlink,omitempty"`
|
|
||||||
|
|
||||||
// change permissions (must already exist)
|
// change permissions (must already exist)
|
||||||
// (--chmod OCTAL PATH)
|
// (--chmod OCTAL PATH)
|
||||||
Chmod map[string]os.FileMode `json:"chmod,omitempty"`
|
Chmod ChmodConfig `json:"chmod,omitempty"`
|
||||||
|
|
||||||
// create a new terminal session
|
// create a new terminal session
|
||||||
// (--new-session)
|
// (--new-session)
|
||||||
|
@ -217,6 +107,34 @@ type UnshareConfig struct {
|
||||||
CGroup bool `json:"cgroup"`
|
CGroup bool `json:"cgroup"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PermConfig[T FSBuilder] struct {
|
||||||
|
// set permissions of next argument
|
||||||
|
// (--perms OCTAL)
|
||||||
|
Mode *os.FileMode `json:"mode,omitempty"`
|
||||||
|
// path to get the new permission
|
||||||
|
// (--bind-data, --file, etc.)
|
||||||
|
Inner T `json:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PermConfig[T]) Path() string {
|
||||||
|
return p.Inner.Path()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PermConfig[T]) Len() int {
|
||||||
|
if p.Mode != nil {
|
||||||
|
return p.Inner.Len() + 2
|
||||||
|
} else {
|
||||||
|
return p.Inner.Len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PermConfig[T]) Append(args *[]string) {
|
||||||
|
if p.Mode != nil {
|
||||||
|
*args = append(*args, intArgs[Perms], strconv.FormatInt(int64(*p.Mode), 8))
|
||||||
|
}
|
||||||
|
p.Inner.Append(args)
|
||||||
|
}
|
||||||
|
|
||||||
type TmpfsConfig struct {
|
type TmpfsConfig struct {
|
||||||
// set size of tmpfs
|
// set size of tmpfs
|
||||||
// (--size BYTES)
|
// (--size BYTES)
|
||||||
|
@ -226,62 +144,47 @@ type TmpfsConfig struct {
|
||||||
Dir string `json:"dir"`
|
Dir string `json:"dir"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type argOf interface {
|
func (t *TmpfsConfig) Path() string {
|
||||||
Value(arg string) (args []string)
|
return t.Dir
|
||||||
Later() bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyToArgOfSlice[T [2]string | string | TmpfsConfig](src []PermConfig[T]) (dst []argOf) {
|
func (t *TmpfsConfig) Len() int {
|
||||||
dst = make([]argOf, len(src))
|
if t.Size > 0 {
|
||||||
for i, arg := range src {
|
return 4
|
||||||
dst[i] = arg
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type PermConfig[T [2]string | string | TmpfsConfig] struct {
|
|
||||||
// append this at the end of the argument stream
|
|
||||||
Last bool
|
|
||||||
|
|
||||||
// set permissions of next argument
|
|
||||||
// (--perms OCTAL)
|
|
||||||
Mode *os.FileMode `json:"mode,omitempty"`
|
|
||||||
// path to get the new permission
|
|
||||||
// (--bind-data, --file, etc.)
|
|
||||||
Path T
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p PermConfig[T]) Later() bool {
|
|
||||||
return p.Last
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p PermConfig[T]) Value(arg string) (args []string) {
|
|
||||||
// max possible size
|
|
||||||
if p.Mode != nil {
|
|
||||||
args = make([]string, 0, 6)
|
|
||||||
args = append(args, "--perms", strconv.FormatInt(int64(*p.Mode), 8))
|
|
||||||
} else {
|
} else {
|
||||||
args = make([]string, 0, 4)
|
return 2
|
||||||
}
|
}
|
||||||
|
}
|
||||||
switch v := any(p.Path).(type) {
|
|
||||||
case string:
|
func (t *TmpfsConfig) Append(args *[]string) {
|
||||||
args = append(args, arg, v)
|
if t.Size > 0 {
|
||||||
return
|
*args = append(*args, intArgs[Size], strconv.Itoa(t.Size))
|
||||||
case [2]string:
|
}
|
||||||
args = append(args, arg, v[0], v[1])
|
*args = append(*args, awkwardArgs[Tmpfs], t.Dir)
|
||||||
return
|
}
|
||||||
case TmpfsConfig:
|
|
||||||
if arg != "--tmpfs" {
|
type SymlinkConfig [2]string
|
||||||
panic("unreachable")
|
|
||||||
}
|
func (s SymlinkConfig) Path() string {
|
||||||
|
return s[1]
|
||||||
if v.Size > 0 {
|
}
|
||||||
args = append(args, "--size", strconv.Itoa(v.Size))
|
|
||||||
}
|
func (s SymlinkConfig) Len() int {
|
||||||
args = append(args, arg, v.Dir)
|
return 3
|
||||||
return
|
}
|
||||||
default:
|
|
||||||
panic("unreachable")
|
func (s SymlinkConfig) Append(args *[]string) {
|
||||||
|
*args = append(*args, awkwardArgs[Symlink], s[0], s[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChmodConfig map[string]os.FileMode
|
||||||
|
|
||||||
|
func (c ChmodConfig) Len() int {
|
||||||
|
return len(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ChmodConfig) Append(args *[]string) {
|
||||||
|
for path, mode := range c {
|
||||||
|
*args = append(*args, pairArgs[Chmod], strconv.FormatInt(int64(mode), 8), path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package bwrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
UID = iota
|
|
||||||
GID
|
|
||||||
|
|
||||||
intC
|
|
||||||
)
|
|
||||||
|
|
||||||
var intArgs = func() (n [intC]string) {
|
|
||||||
n[UID] = "--uid"
|
|
||||||
n[GID] = "--gid"
|
|
||||||
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
func (c *Config) intArgs() (n [intC]*int) {
|
|
||||||
n[UID] = c.UID
|
|
||||||
n[GID] = c.GID
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package bwrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
Tmpfs = iota
|
|
||||||
Dir
|
|
||||||
Symlink
|
|
||||||
|
|
||||||
interfaceC
|
|
||||||
)
|
|
||||||
|
|
||||||
var interfaceArgs = func() (g [interfaceC]string) {
|
|
||||||
g[Tmpfs] = "--tmpfs"
|
|
||||||
g[Dir] = "--dir"
|
|
||||||
g[Symlink] = "--symlink"
|
|
||||||
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
func (c *Config) interfaceArgs() (g [interfaceC][]argOf) {
|
|
||||||
g[Tmpfs] = copyToArgOfSlice(c.Tmpfs)
|
|
||||||
g[Dir] = copyToArgOfSlice(c.Dir)
|
|
||||||
g[Symlink] = copyToArgOfSlice(c.Symlink)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package bwrap
|
|
||||||
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
const (
|
|
||||||
SetEnv = iota
|
|
||||||
|
|
||||||
Bind
|
|
||||||
BindTry
|
|
||||||
DevBind
|
|
||||||
DevBindTry
|
|
||||||
ROBind
|
|
||||||
ROBindTry
|
|
||||||
|
|
||||||
Chmod
|
|
||||||
|
|
||||||
pairC
|
|
||||||
)
|
|
||||||
|
|
||||||
var pairArgs = func() (n [pairC]string) {
|
|
||||||
n[SetEnv] = "--setenv"
|
|
||||||
|
|
||||||
n[Bind] = "--bind"
|
|
||||||
n[BindTry] = "--bind-try"
|
|
||||||
n[DevBind] = "--dev-bind"
|
|
||||||
n[DevBindTry] = "--dev-bind-try"
|
|
||||||
n[ROBind] = "--ro-bind"
|
|
||||||
n[ROBindTry] = "--ro-bind-try"
|
|
||||||
|
|
||||||
n[Chmod] = "--chmod"
|
|
||||||
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
func (c *Config) pairArgs() (n [pairC][][2]string) {
|
|
||||||
n[SetEnv] = make([][2]string, 0, len(c.SetEnv))
|
|
||||||
for k, v := range c.SetEnv {
|
|
||||||
n[SetEnv] = append(n[SetEnv], [2]string{k, v})
|
|
||||||
}
|
|
||||||
|
|
||||||
n[Bind] = c.Bind
|
|
||||||
n[BindTry] = c.BindTry
|
|
||||||
n[DevBind] = c.DevBind
|
|
||||||
n[DevBindTry] = c.DevBindTry
|
|
||||||
n[ROBind] = c.ROBind
|
|
||||||
n[ROBindTry] = c.ROBindTry
|
|
||||||
|
|
||||||
n[Chmod] = make([][2]string, 0, len(c.Chmod))
|
|
||||||
for path, octal := range c.Chmod {
|
|
||||||
n[Chmod] = append(n[Chmod], [2]string{strconv.FormatInt(int64(octal), 8), path})
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
package bwrap
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bind binds mount src on host to dest in sandbox.
|
||||||
|
|
||||||
|
Bind(src, dest) bind mount host path readonly on sandbox
|
||||||
|
(--ro-bind SRC DEST).
|
||||||
|
Bind(src, dest, true) equal to ROBind but ignores non-existent host path
|
||||||
|
(--ro-bind-try SRC DEST).
|
||||||
|
|
||||||
|
Bind(src, dest, false, true) bind mount host path on sandbox.
|
||||||
|
(--bind SRC DEST).
|
||||||
|
Bind(src, dest, true, true) equal to Bind but ignores non-existent host path
|
||||||
|
(--bind-try SRC DEST).
|
||||||
|
|
||||||
|
Bind(src, dest, false, true, true) bind mount host path on sandbox, allowing device access
|
||||||
|
(--dev-bind SRC DEST).
|
||||||
|
Bind(src, dest, true, true, true) equal to DevBind but ignores non-existent host path
|
||||||
|
(--dev-bind-try SRC DEST).
|
||||||
|
*/
|
||||||
|
func (c *Config) Bind(src, dest string, opts ...bool) *Config {
|
||||||
|
var (
|
||||||
|
try bool
|
||||||
|
write bool
|
||||||
|
dev bool
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(opts) > 0 {
|
||||||
|
try = opts[0]
|
||||||
|
}
|
||||||
|
if len(opts) > 1 {
|
||||||
|
write = opts[1]
|
||||||
|
}
|
||||||
|
if len(opts) > 2 {
|
||||||
|
dev = opts[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
if dev {
|
||||||
|
if try {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[DevBindTry], src, dest})
|
||||||
|
} else {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[DevBind], src, dest})
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
} else if write {
|
||||||
|
if try {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[BindTry], src, dest})
|
||||||
|
} else {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[Bind], src, dest})
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
} else {
|
||||||
|
if try {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[ROBindTry], src, dest})
|
||||||
|
} else {
|
||||||
|
c.Filesystem = append(c.Filesystem, &pairF{pairArgs[ROBind], src, dest})
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemountRO remount path as readonly; does not recursively remount
|
||||||
|
// (--remount-ro DEST)
|
||||||
|
func (c *Config) RemountRO(dest string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &stringF{stringArgs[RemountRO], dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Procfs mount new procfs in sandbox
|
||||||
|
// (--proc DEST)
|
||||||
|
func (c *Config) Procfs(dest string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &stringF{stringArgs[Procfs], dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// DevTmpfs mount new dev in sandbox
|
||||||
|
// (--dev DEST)
|
||||||
|
func (c *Config) DevTmpfs(dest string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &stringF{stringArgs[DevTmpfs], dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tmpfs mount new tmpfs in sandbox
|
||||||
|
// (--tmpfs DEST)
|
||||||
|
func (c *Config) Tmpfs(dest string, size int, perm ...os.FileMode) *Config {
|
||||||
|
tmpfs := &PermConfig[*TmpfsConfig]{Inner: &TmpfsConfig{Dir: dest}}
|
||||||
|
if size >= 0 {
|
||||||
|
tmpfs.Inner.Size = size
|
||||||
|
}
|
||||||
|
if len(perm) == 1 {
|
||||||
|
tmpfs.Mode = &perm[0]
|
||||||
|
}
|
||||||
|
c.Filesystem = append(c.Filesystem, tmpfs)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mqueue mount new mqueue in sandbox
|
||||||
|
// (--mqueue DEST)
|
||||||
|
func (c *Config) Mqueue(dest string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &stringF{stringArgs[Mqueue], dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dir create dir in sandbox
|
||||||
|
// (--dir DEST)
|
||||||
|
func (c *Config) Dir(dest string) *Config {
|
||||||
|
c.Filesystem = append(c.Filesystem, &stringF{stringArgs[Dir], dest})
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Symlink create symlink within sandbox
|
||||||
|
// (--symlink SRC DEST)
|
||||||
|
func (c *Config) Symlink(src, dest string, perm ...os.FileMode) *Config {
|
||||||
|
symlink := &PermConfig[SymlinkConfig]{Inner: SymlinkConfig{src, dest}}
|
||||||
|
if len(perm) == 1 {
|
||||||
|
symlink.Mode = &perm[0]
|
||||||
|
}
|
||||||
|
c.Filesystem = append(c.Filesystem, symlink)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUID sets custom uid in the sandbox, requires new user namespace (--uid UID).
|
||||||
|
func (c *Config) SetUID(uid int) *Config {
|
||||||
|
if uid >= 0 {
|
||||||
|
c.UID = &uid
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGID sets custom gid in the sandbox, requires new user namespace (--gid GID).
|
||||||
|
func (c *Config) SetGID(gid int) *Config {
|
||||||
|
if gid >= 0 {
|
||||||
|
c.GID = &gid
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
package bwrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
Hostname = iota
|
|
||||||
Chdir
|
|
||||||
UnsetEnv
|
|
||||||
LockFile
|
|
||||||
RemountRO
|
|
||||||
Procfs
|
|
||||||
DevTmpfs
|
|
||||||
Mqueue
|
|
||||||
|
|
||||||
stringC
|
|
||||||
)
|
|
||||||
|
|
||||||
var stringArgs = func() (n [stringC]string) {
|
|
||||||
n[Hostname] = "--hostname"
|
|
||||||
n[Chdir] = "--chdir"
|
|
||||||
n[UnsetEnv] = "--unsetenv"
|
|
||||||
n[LockFile] = "--lock-file"
|
|
||||||
n[RemountRO] = "--remount-ro"
|
|
||||||
n[Procfs] = "--proc"
|
|
||||||
n[DevTmpfs] = "--dev"
|
|
||||||
n[Mqueue] = "--mqueue"
|
|
||||||
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
func (c *Config) stringArgs() (n [stringC][]string) {
|
|
||||||
if c.Hostname != "" {
|
|
||||||
n[Hostname] = []string{c.Hostname}
|
|
||||||
}
|
|
||||||
if c.Chdir != "" {
|
|
||||||
n[Chdir] = []string{c.Chdir}
|
|
||||||
}
|
|
||||||
n[UnsetEnv] = c.UnsetEnv
|
|
||||||
n[LockFile] = c.LockFile
|
|
||||||
n[RemountRO] = c.RemountRO
|
|
||||||
n[Procfs] = c.Procfs
|
|
||||||
n[DevTmpfs] = c.DevTmpfs
|
|
||||||
n[Mqueue] = c.Mqueue
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -13,40 +13,34 @@ func TestConfig_Args(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "xdg-dbus-proxy constraint sample",
|
name: "xdg-dbus-proxy constraint sample",
|
||||||
conf: &Config{
|
conf: (&Config{
|
||||||
Unshare: nil,
|
Unshare: nil,
|
||||||
UserNS: false,
|
UserNS: false,
|
||||||
Clearenv: true,
|
Clearenv: true,
|
||||||
Symlink: []PermConfig[[2]string]{
|
|
||||||
{Path: [2]string{"usr/bin", "/bin"}},
|
|
||||||
{Path: [2]string{"var/home", "/home"}},
|
|
||||||
{Path: [2]string{"usr/lib", "/lib"}},
|
|
||||||
{Path: [2]string{"usr/lib64", "/lib64"}},
|
|
||||||
{Path: [2]string{"run/media", "/media"}},
|
|
||||||
{Path: [2]string{"var/mnt", "/mnt"}},
|
|
||||||
{Path: [2]string{"var/opt", "/opt"}},
|
|
||||||
{Path: [2]string{"sysroot/ostree", "/ostree"}},
|
|
||||||
{Path: [2]string{"var/roothome", "/root"}},
|
|
||||||
{Path: [2]string{"usr/sbin", "/sbin"}},
|
|
||||||
{Path: [2]string{"var/srv", "/srv"}},
|
|
||||||
},
|
|
||||||
Bind: [][2]string{
|
|
||||||
{"/run", "/run"},
|
|
||||||
{"/tmp", "/tmp"},
|
|
||||||
{"/var", "/var"},
|
|
||||||
{"/run/user/1971/.dbus-proxy/", "/run/user/1971/.dbus-proxy/"},
|
|
||||||
},
|
|
||||||
ROBind: [][2]string{
|
|
||||||
{"/boot", "/boot"},
|
|
||||||
{"/dev", "/dev"},
|
|
||||||
{"/proc", "/proc"},
|
|
||||||
{"/sys", "/sys"},
|
|
||||||
{"/sysroot", "/sysroot"},
|
|
||||||
{"/usr", "/usr"},
|
|
||||||
{"/etc", "/etc"},
|
|
||||||
},
|
|
||||||
DieWithParent: true,
|
DieWithParent: true,
|
||||||
},
|
}).
|
||||||
|
Symlink("usr/bin", "/bin").
|
||||||
|
Symlink("var/home", "/home").
|
||||||
|
Symlink("usr/lib", "/lib").
|
||||||
|
Symlink("usr/lib64", "/lib64").
|
||||||
|
Symlink("run/media", "/media").
|
||||||
|
Symlink("var/mnt", "/mnt").
|
||||||
|
Symlink("var/opt", "/opt").
|
||||||
|
Symlink("sysroot/ostree", "/ostree").
|
||||||
|
Symlink("var/roothome", "/root").
|
||||||
|
Symlink("usr/sbin", "/sbin").
|
||||||
|
Symlink("var/srv", "/srv").
|
||||||
|
Bind("/run", "/run", false, true).
|
||||||
|
Bind("/tmp", "/tmp", false, true).
|
||||||
|
Bind("/var", "/var", false, true).
|
||||||
|
Bind("/run/user/1971/.dbus-proxy/", "/run/user/1971/.dbus-proxy/", false, true).
|
||||||
|
Bind("/boot", "/boot").
|
||||||
|
Bind("/dev", "/dev").
|
||||||
|
Bind("/proc", "/proc").
|
||||||
|
Bind("/sys", "/sys").
|
||||||
|
Bind("/sysroot", "/sysroot").
|
||||||
|
Bind("/usr", "/usr").
|
||||||
|
Bind("/etc", "/etc"),
|
||||||
want: []string{
|
want: []string{
|
||||||
"--unshare-all",
|
"--unshare-all",
|
||||||
"--unshare-user",
|
"--unshare-user",
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/gob"
|
||||||
|
"os"
|
||||||
|
|
||||||
"git.ophivana.moe/cat/fortify/dbus"
|
"git.ophivana.moe/cat/fortify/dbus"
|
||||||
"git.ophivana.moe/cat/fortify/helper/bwrap"
|
"git.ophivana.moe/cat/fortify/helper/bwrap"
|
||||||
"git.ophivana.moe/cat/fortify/internal/state"
|
"git.ophivana.moe/cat/fortify/internal/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
gob.Register(new(bwrap.PermConfig[*bwrap.TmpfsConfig]))
|
||||||
|
}
|
||||||
|
|
||||||
// Config is used to seal an *App
|
// Config is used to seal an *App
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// D-Bus application ID
|
// D-Bus application ID
|
||||||
|
@ -55,7 +62,7 @@ type SandboxConfig struct {
|
||||||
// sandbox host filesystem access
|
// sandbox host filesystem access
|
||||||
Filesystem []*FilesystemConfig `json:"filesystem"`
|
Filesystem []*FilesystemConfig `json:"filesystem"`
|
||||||
// tmpfs mount points to mount last
|
// tmpfs mount points to mount last
|
||||||
Tmpfs []bwrap.TmpfsConfig `json:"tmpfs"`
|
Tmpfs []string `json:"tmpfs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilesystemConfig struct {
|
type FilesystemConfig struct {
|
||||||
|
@ -71,61 +78,39 @@ type FilesystemConfig struct {
|
||||||
Must bool `json:"require,omitempty"`
|
Must bool `json:"require,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bwrap returns the address of the corresponding bwrap.Config to s.
|
||||||
|
// Note that remaining tmpfs entries must be queued by the caller prior to launch.
|
||||||
func (s *SandboxConfig) Bwrap() *bwrap.Config {
|
func (s *SandboxConfig) Bwrap() *bwrap.Config {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nobody := 65534
|
conf := (&bwrap.Config{
|
||||||
conf := &bwrap.Config{
|
|
||||||
Net: s.Net,
|
Net: s.Net,
|
||||||
UserNS: s.UserNS,
|
UserNS: s.UserNS,
|
||||||
UID: &nobody,
|
|
||||||
GID: &nobody,
|
|
||||||
Hostname: s.Hostname,
|
Hostname: s.Hostname,
|
||||||
Clearenv: true,
|
Clearenv: true,
|
||||||
SetEnv: s.Env,
|
SetEnv: s.Env,
|
||||||
Procfs: []string{"/proc"},
|
|
||||||
DevTmpfs: []string{"/dev"},
|
|
||||||
Mqueue: []string{"/dev/mqueue"},
|
|
||||||
NewSession: !s.NoNewSession,
|
NewSession: !s.NoNewSession,
|
||||||
DieWithParent: true,
|
DieWithParent: true,
|
||||||
AsInit: true,
|
AsInit: true,
|
||||||
}
|
|
||||||
|
// initialise map
|
||||||
|
Chmod: make(map[string]os.FileMode),
|
||||||
|
}).
|
||||||
|
SetUID(65534).SetGID(65534).
|
||||||
|
Procfs("/proc").DevTmpfs("/dev").Mqueue("/dev/mqueue")
|
||||||
|
|
||||||
for _, c := range s.Filesystem {
|
for _, c := range s.Filesystem {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
p := [2]string{c.Src, c.Dst}
|
src := c.Src
|
||||||
|
dest := c.Dst
|
||||||
if c.Dst == "" {
|
if c.Dst == "" {
|
||||||
p[1] = c.Src
|
dest = c.Src
|
||||||
}
|
}
|
||||||
|
conf.Bind(src, dest, !c.Must, c.Write, c.Device)
|
||||||
switch {
|
|
||||||
case c.Device:
|
|
||||||
if c.Must {
|
|
||||||
conf.DevBind = append(conf.DevBind, p)
|
|
||||||
} else {
|
|
||||||
conf.DevBindTry = append(conf.DevBindTry, p)
|
|
||||||
}
|
|
||||||
case c.Write:
|
|
||||||
if c.Must {
|
|
||||||
conf.Bind = append(conf.Bind, p)
|
|
||||||
} else {
|
|
||||||
conf.BindTry = append(conf.BindTry, p)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if c.Must {
|
|
||||||
conf.ROBind = append(conf.ROBind, p)
|
|
||||||
} else {
|
|
||||||
conf.ROBindTry = append(conf.ROBindTry, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tmpfs := range s.Tmpfs {
|
|
||||||
conf.Tmpfs = append(conf.Tmpfs, bwrap.PermConfig[bwrap.TmpfsConfig]{Path: tmpfs, Last: true})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
|
@ -164,9 +149,7 @@ func Template() *Config {
|
||||||
{Src: "/data/user/0", Dst: "/data/data", Write: true, Must: true},
|
{Src: "/data/user/0", Dst: "/data/data", Write: true, Must: true},
|
||||||
{Src: "/var/tmp", Write: true},
|
{Src: "/var/tmp", Write: true},
|
||||||
},
|
},
|
||||||
Tmpfs: []bwrap.TmpfsConfig{
|
Tmpfs: []string{"/var/run/nscd"},
|
||||||
{Size: 8 * 1024, Dir: "/var/run/nscd"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
SystemBus: &dbus.Config{
|
SystemBus: &dbus.Config{
|
||||||
See: nil,
|
See: nil,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.ophivana.moe/cat/fortify/dbus"
|
"git.ophivana.moe/cat/fortify/dbus"
|
||||||
"git.ophivana.moe/cat/fortify/helper/bwrap"
|
|
||||||
"git.ophivana.moe/cat/fortify/internal"
|
"git.ophivana.moe/cat/fortify/internal"
|
||||||
"git.ophivana.moe/cat/fortify/internal/state"
|
"git.ophivana.moe/cat/fortify/internal/state"
|
||||||
"git.ophivana.moe/cat/fortify/internal/verbose"
|
"git.ophivana.moe/cat/fortify/internal/verbose"
|
||||||
|
@ -163,7 +162,7 @@ func (a *app) Seal(config *Config) error {
|
||||||
// hide nscd from sandbox if present
|
// hide nscd from sandbox if present
|
||||||
nscd := "/var/run/nscd"
|
nscd := "/var/run/nscd"
|
||||||
if _, err := os.Stat(nscd); !errors.Is(err, os.ErrNotExist) {
|
if _, err := os.Stat(nscd); !errors.Is(err, os.ErrNotExist) {
|
||||||
conf.Tmpfs = append(conf.Tmpfs, bwrap.TmpfsConfig{Size: 8 * 1024, Dir: nscd})
|
conf.Tmpfs = append(conf.Tmpfs, nscd)
|
||||||
}
|
}
|
||||||
// bind GPU stuff
|
// bind GPU stuff
|
||||||
if config.Confinement.Enablements.Has(state.EnableX) || config.Confinement.Enablements.Has(state.EnableWayland) {
|
if config.Confinement.Enablements.Has(state.EnableX) || config.Confinement.Enablements.Has(state.EnableWayland) {
|
||||||
|
@ -172,6 +171,7 @@ func (a *app) Seal(config *Config) error {
|
||||||
config.Confinement.Sandbox = conf
|
config.Confinement.Sandbox = conf
|
||||||
}
|
}
|
||||||
seal.sys.bwrap = config.Confinement.Sandbox.Bwrap()
|
seal.sys.bwrap = config.Confinement.Sandbox.Bwrap()
|
||||||
|
seal.sys.tmpfs = config.Confinement.Sandbox.Tmpfs
|
||||||
if seal.sys.bwrap.SetEnv == nil {
|
if seal.sys.bwrap.SetEnv == nil {
|
||||||
seal.sys.bwrap.SetEnv = make(map[string]string)
|
seal.sys.bwrap.SetEnv = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,12 +65,12 @@ func (seal *appSeal) shareDBus(config [2]*dbus.Config) error {
|
||||||
// share proxy sockets
|
// share proxy sockets
|
||||||
sessionInner := path.Join(seal.sys.runtime, "bus")
|
sessionInner := path.Join(seal.sys.runtime, "bus")
|
||||||
seal.sys.setEnv(dbusSessionBusAddress, "unix:path="+sessionInner)
|
seal.sys.setEnv(dbusSessionBusAddress, "unix:path="+sessionInner)
|
||||||
seal.sys.bind(sessionBus[1], sessionInner, true)
|
seal.sys.bwrap.Bind(sessionBus[1], sessionInner)
|
||||||
seal.sys.updatePerm(sessionBus[1], acl.Read, acl.Write)
|
seal.sys.updatePerm(sessionBus[1], acl.Read, acl.Write)
|
||||||
if seal.sys.dbusSystem {
|
if seal.sys.dbusSystem {
|
||||||
systemInner := "/run/dbus/system_bus_socket"
|
systemInner := "/run/dbus/system_bus_socket"
|
||||||
seal.sys.setEnv(dbusSystemBusAddress, "unix:path="+systemInner)
|
seal.sys.setEnv(dbusSystemBusAddress, "unix:path="+systemInner)
|
||||||
seal.sys.bind(systemBus[1], systemInner, true)
|
seal.sys.bwrap.Bind(systemBus[1], systemInner)
|
||||||
seal.sys.updatePerm(systemBus[1], acl.Read, acl.Write)
|
seal.sys.updatePerm(systemBus[1], acl.Read, acl.Write)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (seal *appSeal) shareDisplay() error {
|
||||||
w := path.Join(seal.sys.runtime, "wayland-0")
|
w := path.Join(seal.sys.runtime, "wayland-0")
|
||||||
seal.sys.link(wp, wpi)
|
seal.sys.link(wp, wpi)
|
||||||
seal.sys.setEnv(waylandDisplay, w)
|
seal.sys.setEnv(waylandDisplay, w)
|
||||||
seal.sys.bind(wpi, w, true)
|
seal.sys.bwrap.Bind(wpi, w)
|
||||||
|
|
||||||
// ensure Wayland socket ACL (e.g. `/run/user/%d/wayland-%d`)
|
// ensure Wayland socket ACL (e.g. `/run/user/%d/wayland-%d`)
|
||||||
seal.sys.updatePermTag(state.EnableWayland, wp, acl.Read, acl.Write, acl.Execute)
|
seal.sys.updatePermTag(state.EnableWayland, wp, acl.Read, acl.Write, acl.Execute)
|
||||||
|
@ -59,7 +59,7 @@ func (seal *appSeal) shareDisplay() error {
|
||||||
} else {
|
} else {
|
||||||
seal.sys.changeHosts(seal.sys.Username)
|
seal.sys.changeHosts(seal.sys.Username)
|
||||||
seal.sys.setEnv(display, d)
|
seal.sys.setEnv(display, d)
|
||||||
seal.sys.bind("/tmp/.X11-unix", "/tmp/.X11-unix", true)
|
seal.sys.bwrap.Bind("/tmp/.X11-unix", "/tmp/.X11-unix")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (seal *appSeal) sharePulse() error {
|
||||||
psi := path.Join(seal.shareLocal, "pulse")
|
psi := path.Join(seal.shareLocal, "pulse")
|
||||||
p := path.Join(seal.sys.runtime, "pulse", "native")
|
p := path.Join(seal.sys.runtime, "pulse", "native")
|
||||||
seal.sys.link(ps, psi)
|
seal.sys.link(ps, psi)
|
||||||
seal.sys.bind(psi, p, true)
|
seal.sys.bwrap.Bind(psi, p)
|
||||||
seal.sys.setEnv(pulseServer, "unix:"+p)
|
seal.sys.setEnv(pulseServer, "unix:"+p)
|
||||||
|
|
||||||
// publish current user's pulse cookie for target user
|
// publish current user's pulse cookie for target user
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"git.ophivana.moe/cat/fortify/acl"
|
"git.ophivana.moe/cat/fortify/acl"
|
||||||
"git.ophivana.moe/cat/fortify/helper/bwrap"
|
|
||||||
"git.ophivana.moe/cat/fortify/internal/state"
|
"git.ophivana.moe/cat/fortify/internal/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,20 +16,13 @@ const (
|
||||||
// shareRuntime queues actions for sharing/ensuring the runtime and share directories
|
// shareRuntime queues actions for sharing/ensuring the runtime and share directories
|
||||||
func (seal *appSeal) shareRuntime() {
|
func (seal *appSeal) shareRuntime() {
|
||||||
// mount tmpfs on inner runtime (e.g. `/run/user/%d`)
|
// mount tmpfs on inner runtime (e.g. `/run/user/%d`)
|
||||||
seal.sys.bwrap.Tmpfs = append(seal.sys.bwrap.Tmpfs,
|
seal.sys.bwrap.Tmpfs("/run/user", 1*1024*1024)
|
||||||
bwrap.PermConfig[bwrap.TmpfsConfig]{
|
seal.sys.bwrap.Tmpfs(seal.sys.runtime, 8*1024*1024)
|
||||||
Path: bwrap.TmpfsConfig{
|
|
||||||
Size: 1 * 1024 * 1024,
|
// point to inner runtime path `/run/user/%d`
|
||||||
Dir: "/run/user",
|
seal.sys.setEnv(xdgRuntimeDir, seal.sys.runtime)
|
||||||
},
|
seal.sys.setEnv(xdgSessionClass, "user")
|
||||||
},
|
seal.sys.setEnv(xdgSessionType, "tty")
|
||||||
bwrap.PermConfig[bwrap.TmpfsConfig]{
|
|
||||||
Path: bwrap.TmpfsConfig{
|
|
||||||
Size: 8 * 1024 * 1024,
|
|
||||||
Dir: seal.sys.runtime,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
// ensure RunDir (e.g. `/run/user/%d/fortify`)
|
// ensure RunDir (e.g. `/run/user/%d/fortify`)
|
||||||
seal.sys.ensure(seal.RunDirPath, 0700)
|
seal.sys.ensure(seal.RunDirPath, 0700)
|
||||||
|
@ -53,22 +45,3 @@ func (seal *appSeal) shareRuntime() {
|
||||||
seal.sys.ensureEphemeral(seal.shareLocal, 0700)
|
seal.sys.ensureEphemeral(seal.shareLocal, 0700)
|
||||||
seal.sys.updatePerm(seal.shareLocal, acl.Execute)
|
seal.sys.updatePerm(seal.shareLocal, acl.Execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (seal *appSeal) shareRuntimeChild() string {
|
|
||||||
// ensure child runtime parent directory (e.g. `/tmp/fortify.%d/runtime`)
|
|
||||||
targetRuntimeParent := path.Join(seal.SharePath, "runtime")
|
|
||||||
seal.sys.ensure(targetRuntimeParent, 0700)
|
|
||||||
seal.sys.updatePermTag(state.EnableLength, targetRuntimeParent, acl.Execute)
|
|
||||||
|
|
||||||
// ensure child runtime directory (e.g. `/tmp/fortify.%d/runtime/%d`)
|
|
||||||
targetRuntime := path.Join(targetRuntimeParent, seal.sys.Uid)
|
|
||||||
seal.sys.ensure(targetRuntime, 0700)
|
|
||||||
seal.sys.updatePermTag(state.EnableLength, targetRuntime, acl.Read, acl.Write, acl.Execute)
|
|
||||||
|
|
||||||
// point to ensured runtime path
|
|
||||||
seal.sys.setEnv(xdgRuntimeDir, targetRuntime)
|
|
||||||
seal.sys.setEnv(xdgSessionClass, "user")
|
|
||||||
seal.sys.setEnv(xdgSessionType, "tty")
|
|
||||||
|
|
||||||
return targetRuntime
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ package app
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"git.ophivana.moe/cat/fortify/acl"
|
||||||
|
"git.ophivana.moe/cat/fortify/internal/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -38,6 +41,24 @@ func (seal *appSeal) shareSystem() {
|
||||||
seal.sys.writeFile(groupPath, []byte("fortify:x:65534:\n"))
|
seal.sys.writeFile(groupPath, []byte("fortify:x:65534:\n"))
|
||||||
|
|
||||||
// bind /etc/passwd and /etc/group
|
// bind /etc/passwd and /etc/group
|
||||||
seal.sys.bind(passwdPath, "/etc/passwd", true)
|
seal.sys.bwrap.Bind(passwdPath, "/etc/passwd")
|
||||||
seal.sys.bind(groupPath, "/etc/group", true)
|
seal.sys.bwrap.Bind(groupPath, "/etc/group")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (seal *appSeal) shareTmpdirChild() string {
|
||||||
|
// ensure child tmpdir parent directory (e.g. `/tmp/fortify.%d/tmpdir`)
|
||||||
|
targetTmpdirParent := path.Join(seal.SharePath, "tmpdir")
|
||||||
|
seal.sys.ensure(targetTmpdirParent, 0700)
|
||||||
|
seal.sys.updatePermTag(state.EnableLength, targetTmpdirParent, acl.Execute)
|
||||||
|
|
||||||
|
// ensure child tmpdir (e.g. `/tmp/fortify.%d/tmpdir/%d`)
|
||||||
|
targetTmpdir := path.Join(targetTmpdirParent, seal.sys.Uid)
|
||||||
|
seal.sys.ensure(targetTmpdir, 01700)
|
||||||
|
seal.sys.updatePermTag(state.EnableLength, targetTmpdir, acl.Read, acl.Write, acl.Execute)
|
||||||
|
seal.sys.bwrap.Bind(targetTmpdir, "/tmp", false, true)
|
||||||
|
|
||||||
|
// mount tmpfs on inner shared directory (e.g. `/tmp/fortify.%d`)
|
||||||
|
seal.sys.bwrap.Tmpfs(seal.SharePath, 1*1024*1024)
|
||||||
|
|
||||||
|
return targetTmpdir
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ func (a *app) Start() error {
|
||||||
a.cmd.Stderr = os.Stderr
|
a.cmd.Stderr = os.Stderr
|
||||||
a.cmd.Dir = a.seal.RunDirPath
|
a.cmd.Dir = a.seal.RunDirPath
|
||||||
|
|
||||||
if wls, err := shim.ServeConfig(confSockPath, &shim.Payload{
|
if wls, err := shim.ServeConfig(confSockPath, a.seal.sys.uid, &shim.Payload{
|
||||||
Argv: a.seal.command,
|
Argv: a.seal.command,
|
||||||
Exec: shimExec,
|
Exec: shimExec,
|
||||||
Bwrap: a.seal.sys.bwrap,
|
Bwrap: a.seal.sys.bwrap,
|
||||||
|
|
|
@ -59,6 +59,7 @@ type appSeal struct {
|
||||||
// appSealTx contains the system-level component of the app seal
|
// appSealTx contains the system-level component of the app seal
|
||||||
type appSealTx struct {
|
type appSealTx struct {
|
||||||
bwrap *bwrap.Config
|
bwrap *bwrap.Config
|
||||||
|
tmpfs []string
|
||||||
|
|
||||||
// reference to D-Bus proxy instance, nil if disabled
|
// reference to D-Bus proxy instance, nil if disabled
|
||||||
dbus *dbus.Proxy
|
dbus *dbus.Proxy
|
||||||
|
@ -110,15 +111,6 @@ func (tx *appSealTx) setEnv(k, v string) {
|
||||||
tx.bwrap.SetEnv[k] = v
|
tx.bwrap.SetEnv[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind mounts a directory within the sandbox
|
|
||||||
func (tx *appSealTx) bind(src, dest string, ro bool) {
|
|
||||||
if !ro {
|
|
||||||
tx.bwrap.Bind = append(tx.bwrap.Bind, [2]string{src, dest})
|
|
||||||
} else {
|
|
||||||
tx.bwrap.ROBind = append(tx.bwrap.ROBind, [2]string{src, dest})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure appends a directory ensure action
|
// ensure appends a directory ensure action
|
||||||
func (tx *appSealTx) ensure(path string, perm os.FileMode) {
|
func (tx *appSealTx) ensure(path string, perm os.FileMode) {
|
||||||
tx.mkdir = append(tx.mkdir, appEnsureEntry{path, perm, false})
|
tx.mkdir = append(tx.mkdir, appEnsureEntry{path, perm, false})
|
||||||
|
@ -183,14 +175,14 @@ func (tx *appSealTx) changeHosts(username string) {
|
||||||
func (tx *appSealTx) writeFile(dst string, data []byte) {
|
func (tx *appSealTx) writeFile(dst string, data []byte) {
|
||||||
tx.files = append(tx.files, [2]string{dst, string(data)})
|
tx.files = append(tx.files, [2]string{dst, string(data)})
|
||||||
tx.updatePerm(dst, acl.Read)
|
tx.updatePerm(dst, acl.Read)
|
||||||
tx.bind(dst, dst, true)
|
tx.bwrap.Bind(dst, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyFile appends a tmpfiles action
|
// copyFile appends a tmpfiles action
|
||||||
func (tx *appSealTx) copyFile(dst, src string) {
|
func (tx *appSealTx) copyFile(dst, src string) {
|
||||||
tx.tmpfiles = append(tx.tmpfiles, [2]string{dst, src})
|
tx.tmpfiles = append(tx.tmpfiles, [2]string{dst, src})
|
||||||
tx.updatePerm(dst, acl.Read)
|
tx.updatePerm(dst, acl.Read)
|
||||||
tx.bind(dst, dst, true)
|
tx.bwrap.Bind(dst, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// link appends a hardlink action
|
// link appends a hardlink action
|
||||||
|
@ -324,6 +316,12 @@ func (tx *appSealTx) commit() error {
|
||||||
|
|
||||||
// disarm partial commit rollback
|
// disarm partial commit rollback
|
||||||
txp = nil
|
txp = nil
|
||||||
|
|
||||||
|
// queue tmpfs at the end of tx.bwrap.Filesystem
|
||||||
|
for _, dest := range tx.tmpfs {
|
||||||
|
tx.bwrap.Tmpfs(dest, 8*1024)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,10 +414,10 @@ func (seal *appSeal) shareAll(bus [2]*dbus.Config) error {
|
||||||
}
|
}
|
||||||
seal.shared = true
|
seal.shared = true
|
||||||
|
|
||||||
|
targetTmpdir := seal.shareTmpdirChild()
|
||||||
|
verbose.Printf("child tmpdir %q configured\n", targetTmpdir)
|
||||||
seal.shareRuntime()
|
seal.shareRuntime()
|
||||||
seal.shareSystem()
|
seal.shareSystem()
|
||||||
targetRuntime := seal.shareRuntimeChild()
|
|
||||||
verbose.Printf("child runtime data dir '%s' configured\n", targetRuntime)
|
|
||||||
if err := seal.shareDisplay(); err != nil {
|
if err := seal.shareDisplay(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,13 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"git.ophivana.moe/cat/fortify/acl"
|
||||||
"git.ophivana.moe/cat/fortify/internal/verbose"
|
"git.ophivana.moe/cat/fortify/internal/verbose"
|
||||||
)
|
)
|
||||||
|
|
||||||
// called in the parent process
|
// called in the parent process
|
||||||
|
|
||||||
func ServeConfig(socket string, payload *Payload, wl string, done chan struct{}) (*net.UnixConn, error) {
|
func ServeConfig(socket string, uid int, payload *Payload, wl string, done chan struct{}) (*net.UnixConn, error) {
|
||||||
var ws *net.UnixConn
|
var ws *net.UnixConn
|
||||||
if payload.WL {
|
if payload.WL {
|
||||||
if f, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: wl, Net: "unix"}); err != nil {
|
if f, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: wl, Net: "unix"}); err != nil {
|
||||||
|
@ -28,7 +29,7 @@ func ServeConfig(socket string, payload *Payload, wl string, done chan struct{})
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
verbose.Println("configuring shim on socket", socket)
|
verbose.Println("configuring shim on socket", socket)
|
||||||
if err = os.Chmod(socket, 0777); err != nil {
|
if err = acl.UpdatePerm(socket, uid, acl.Read, acl.Write, acl.Execute); err != nil {
|
||||||
fmt.Println("fortify: cannot change permissions of shim setup socket:", err)
|
fmt.Println("fortify: cannot change permissions of shim setup socket:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ func ServeConfig(socket string, payload *Payload, wl string, done chan struct{})
|
||||||
} else {
|
} else {
|
||||||
if err = gob.NewEncoder(conn).Encode(*payload); err != nil {
|
if err = gob.NewEncoder(conn).Encode(*payload); err != nil {
|
||||||
fmt.Println("fortify: cannot stream shim payload:", err)
|
fmt.Println("fortify: cannot stream shim payload:", err)
|
||||||
|
_ = os.Remove(socket)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue