diff --git a/fs/fs.go b/fs/fs.go index 8be2017..e8677e3 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -41,6 +41,20 @@ func (fs *Filesystem) Xpra() string { return fs.xpra } +func (fs *Filesystem) AddBindWhitelist(path, target string, readonly bool) error { + for _, fsitem := range fs.whitelist { + if fsitem.path == path { + return nil + } + } + item, err := fs.newItem(path, target, readonly) + if err != nil { + return err + } + fs.whitelist = append(fs.whitelist, item) + return item.bindItem() +} + func (fs *Filesystem) addWhitelist(path, target string, readonly bool) error { item, err := fs.newItem(path, target, readonly) if err != nil { diff --git a/oz-daemon/client.go b/oz-daemon/client.go index 41a4e38..0e8d98f 100644 --- a/oz-daemon/client.go +++ b/oz-daemon/client.go @@ -3,8 +3,10 @@ package daemon import ( "errors" "fmt" - "github.com/subgraph/oz/ipc" + "os" "strconv" + + "github.com/subgraph/oz/ipc" ) func clientConnect() (*ipc.MsgConn, error) { @@ -56,9 +58,12 @@ func Launch(arg string, args, env []string) error { if err != nil { return err } + pwd, _ := os.Getwd() + resp, err := clientSend(&LaunchMsg{ Index: idx, Name: name, + Pwd: pwd, Args: args, Env: env, }) diff --git a/oz-daemon/daemon.go b/oz-daemon/daemon.go index d29105f..d1e6d18 100644 --- a/oz-daemon/daemon.go +++ b/oz-daemon/daemon.go @@ -134,11 +134,11 @@ func (d *daemonState) handleLaunch(msg *LaunchMsg, m *ipc.Message) error { } if sbox := d.getRunningSandboxByName(p.Name); sbox != nil { d.Info("Found running sandbox for `%s`, running program there", p.Name) - sbox.launchProgram(msg.Args, d.log) + sbox.launchProgram(msg.Pwd, msg.Args, d.log) } else { d.Debug("Would launch %s", p.Name) env := d.sanitizeEnvironment(p, msg.Env) - _, err = d.launch(p, msg.Args, env, m.Ucred.Uid, m.Ucred.Gid, d.log) + _, err = d.launch(p, msg.Pwd, msg.Args, env, m.Ucred.Uid, m.Ucred.Gid, d.log) if err != nil { d.Warning("Launch of %s failed: %v", p.Name, err) return m.Respond(&ErrorMsg{err.Error()}) diff --git a/oz-daemon/launch.go b/oz-daemon/launch.go index 3990f49..2ae79e7 100644 --- a/oz-daemon/launch.go +++ b/oz-daemon/launch.go @@ -4,9 +4,11 @@ import ( "bufio" "fmt" "io" + "os" "os/exec" "os/user" "path" + "path/filepath" "sync" "syscall" @@ -72,7 +74,7 @@ func createInitCommand(initPath, name, chroot string, env []string, uid uint32, return cmd } -func (d *daemonState) launch(p *oz.Profile, args, env []string, uid, gid uint32, log *logging.Logger) (*Sandbox, error) { +func (d *daemonState) launch(p *oz.Profile, pwd string, args, env []string, uid, gid uint32, log *logging.Logger) (*Sandbox, error) { u, err := user.LookupId(fmt.Sprintf("%d", uid)) if err != nil { return nil, fmt.Errorf("failed to lookup user for uid=%d: %v", uid, err) @@ -135,7 +137,7 @@ func (d *daemonState) launch(p *oz.Profile, args, env []string, uid, gid uint32, go func () { sbox.ready.Wait() - go sbox.launchProgram(args, log) + go sbox.launchProgram(pwd, args, log) }() if sbox.profile.XServer.Enabled { @@ -149,7 +151,19 @@ func (d *daemonState) launch(p *oz.Profile, args, env []string, uid, gid uint32, return sbox, nil } -func (sbox *Sandbox) launchProgram(args []string, log *logging.Logger) { +func (sbox *Sandbox) launchProgram(pwd string, args []string, log *logging.Logger) { + for _, fpath := range args { + if _, err := os.Stat(fpath); err == nil { + if filepath.IsAbs(fpath) == false { + fpath = path.Join(pwd, fpath) + } + log.Info("Adding file `%s` to sandbox `%s`.", fpath, sbox.profile.Name) + if err := sbox.fs.AddBindWhitelist(fpath, fpath, false); err != nil { + log.Warning("Error adding file `%s`!", fpath) + } + } + } + err := ozinit.RunProgram(sbox.addr, args) if err != nil { log.Error("start shell command failed: %v", err) diff --git a/oz-daemon/protocol.go b/oz-daemon/protocol.go index 6328ad1..058edeb 100644 --- a/oz-daemon/protocol.go +++ b/oz-daemon/protocol.go @@ -33,6 +33,7 @@ type ListProfilesResp struct { type LaunchMsg struct { Index int "Launch" Name string + Pwd string Args []string Env []string }