From a7e891f4fca9430028b6c89dfa1e790576753c66 Mon Sep 17 00:00:00 2001 From: xSmurf Date: Tue, 21 Jul 2015 00:29:52 +0000 Subject: [PATCH] Tentative: Adding seccomp default blacklist to xpra/xorg server and client --- oz-daemon/launch.go | 2 ++ oz-init/init.go | 12 +++++++++--- oz-seccomp/seccomp.go | 20 ++++++-------------- xpra/client.go | 12 ++++++++++-- xpra/server.go | 24 ++++++++++++++++-------- xpra/xpra.go | 24 +++++++++++++++++++++++- 6 files changed, 66 insertions(+), 28 deletions(-) diff --git a/oz-daemon/launch.go b/oz-daemon/launch.go index 54671ad..cb6f10e 100644 --- a/oz-daemon/launch.go +++ b/oz-daemon/launch.go @@ -406,12 +406,14 @@ func (sbox *Sandbox) startXpraClient() { &sbox.profile.XServer, uint64(sbox.display), sbox.cred, + path.Join(sbox.daemon.config.PrefixPath, "bin", "oz-seccomp"), xpraPath, sbox.profile.Name, sbox.daemon.log) sbox.xpra.Process.Env = append(sbox.rawEnv, sbox.xpra.Process.Env...) + //sbox.daemon.log.Debug("%s %s", strings.Join(sbox.xpra.Process.Env, " "), strings.Join(sbox.xpra.Process.Args, " ")) if sbox.daemon.config.LogXpra { sbox.setupXpraLogging() } diff --git a/oz-init/init.go b/oz-init/init.go index 7e10912..397eef5 100644 --- a/oz-init/init.go +++ b/oz-init/init.go @@ -243,7 +243,7 @@ func (st *initState) getDbusSession() error { } dcmd := exec.Command("/usr/bin/dbus-launch", args...) dcmd.Env = append([]string{}, st.launchEnv...) - st.log.Debug("%s /usr/bin/dbus-launch %s", strings.Join(dcmd.Env, " "), strings.Join(args, " ")) + //st.log.Debug("%s /usr/bin/dbus-launch %s", strings.Join(dcmd.Env, " "), strings.Join(args, " ")) dcmd.SysProcAttr = &syscall.SysProcAttr{} dcmd.SysProcAttr.Credential = &syscall.Credential{ Uid: st.uid, @@ -281,10 +281,16 @@ func (st *initState) startXpraServer() { } workdir := path.Join(st.user.HomeDir, ".Xoz", st.profile.Name) st.log.Info("xpra work dir is %s", workdir) - xpra := xpra.NewServer(&st.profile.XServer, uint64(st.display), workdir) + spath := path.Join(st.config.PrefixPath, "bin", "oz-seccomp") + xpra := xpra.NewServer(&st.profile.XServer, uint64(st.display), spath, workdir) + //st.log.Debug("%s %s", strings.Join(xpra.Process.Env, " "), strings.Join(xpra.Process.Args, " ")) + if xpra == nil { + st.log.Error("Error creating xpra server command") + os.Exit(1) + } p, err := xpra.Process.StderrPipe() if err != nil { - st.log.Warning("Error creating stderr pipe for xpra output: %v", err) + st.log.Error("Error creating stderr pipe for xpra output: %v", err) os.Exit(1) } go st.readXpraOutput(p) diff --git a/oz-seccomp/seccomp.go b/oz-seccomp/seccomp.go index 864040c..de160ec 100644 --- a/oz-seccomp/seccomp.go +++ b/oz-seccomp/seccomp.go @@ -22,19 +22,18 @@ func createLogger() *logging.Logger { return l } -func Main() { - log := createLogger() +var log *logging.Logger + +func init() { + log = createLogger() +} +func Main() { if len(os.Args) < 3 { log.Error("seccomp-wrapper: Not enough arguments.") os.Exit(1) } - if os.Getppid() != 1 { - log.Error("oz-seccomp wrapper must be called from oz-init!") - os.Exit(1) - } - cmd := os.Args[2] cmdArgs := os.Args[2:] @@ -54,14 +53,7 @@ func Main() { log.Error("unable to decode profile data: %v", err) os.Exit(1) } -/* - p, err := loadProfile(config.ProfileDir, pname) - if err != nil { - log.Error("Could not load profile %s: %v", pname, err) - os.Exit(1) - } -*/ switch os.Args[1] { case "-w": if p.Seccomp.Seccomp_Whitelist == "" { diff --git a/xpra/client.go b/xpra/client.go index b57e653..e9abc30 100644 --- a/xpra/client.go +++ b/xpra/client.go @@ -21,13 +21,16 @@ var xpraClientDefaultArgs = []string{ "--no-keyboard-sync", } -func NewClient(config *oz.XServerConf, display uint64, cred *syscall.Credential, workdir string, hostname string, log *logging.Logger) *Xpra { +func NewClient(config *oz.XServerConf, display uint64, cred *syscall.Credential, spath, workdir, hostname string, log *logging.Logger) *Xpra { x := new(Xpra) x.Config = config x.Display = display x.WorkDir = workdir x.xpraArgs = prepareClientArgs(config, display, workdir, log) - x.Process = exec.Command("/usr/bin/xpra", x.xpraArgs...) + + x.xpraArgs = append([]string{"-b", "/usr/bin/xpra"}, x.xpraArgs...) + + x.Process = exec.Command(spath, x.xpraArgs...) x.Process.SysProcAttr = &syscall.SysProcAttr{ Credential: cred, } @@ -36,6 +39,11 @@ func NewClient(config *oz.XServerConf, display uint64, cred *syscall.Credential, fmt.Sprintf("TMPDIR=%s", workdir), fmt.Sprintf("XPRA_SOCKET_HOSTNAME=%s", hostname), } + + if err := writeFakeProfile(x.Process); err != nil { + return nil + } + return x } diff --git a/xpra/server.go b/xpra/server.go index 26c4b9d..3fd0509 100644 --- a/xpra/server.go +++ b/xpra/server.go @@ -2,9 +2,10 @@ package xpra import ( "fmt" - "github.com/subgraph/oz" "os" "os/exec" + + "github.com/subgraph/oz" ) var xpraServerDefaultArgs = []string{ @@ -13,32 +14,39 @@ var xpraServerDefaultArgs = []string{ "--input-method=keep", } -func NewServer(config *oz.XServerConf, display uint64, workdir string) *Xpra { +func NewServer(config *oz.XServerConf, display uint64, spath, workdir string) *Xpra { x := new(Xpra) x.Config = config x.Display = display x.WorkDir = workdir x.xpraArgs = prepareServerArgs(config, display, workdir) - x.Process = exec.Command("/usr/bin/xpra", x.xpraArgs...) + + x.xpraArgs = append([]string{"-b", "/usr/bin/xpra"}, x.xpraArgs...) + + x.Process = exec.Command(spath, x.xpraArgs...) x.Process.Env = append(os.Environ(), "TMPDIR="+workdir, ) + if err := writeFakeProfile(x.Process); err != nil { + return nil + } + return x } func prepareServerArgs(config *oz.XServerConf, display uint64, workdir string) []string { args := getDefaultArgs(config) args = append(args, xpraServerDefaultArgs...) - args = append(args, - fmt.Sprintf("--socket-dir=%s", workdir), - "start", - fmt.Sprintf(":%d", display), - ) if config.AudioMode == oz.PROFILE_AUDIO_FULL || config.AudioMode == oz.PROFILE_AUDIO_SPEAKER { args = append(args, "--pulseaudio") } else { args = append(args, "--no-pulseaudio") } + args = append(args, + fmt.Sprintf("--socket-dir=%s", workdir), + "start", + fmt.Sprintf(":%d", display), + ) return args } diff --git a/xpra/xpra.go b/xpra/xpra.go index 745c6ae..0674dd1 100644 --- a/xpra/xpra.go +++ b/xpra/xpra.go @@ -1,15 +1,19 @@ package xpra import ( + "bytes" + "encoding/json" "errors" "fmt" - "github.com/subgraph/oz" + "io" "os" "os/exec" "os/user" "path" "strconv" "syscall" + + "github.com/subgraph/oz" ) type Xpra struct { @@ -121,3 +125,21 @@ func userIds(user *user.User) (int, int, error) { } return uid, gid, nil } + +func writeFakeProfile(cmd *exec.Cmd) error { + pi, err := cmd.StdinPipe() + if err != nil { + return nil + } + emptyProfile := new(oz.Profile) + emptyProfile.Seccomp.Mode = "blacklist" + emptyProfile.Seccomp.Enforce = true + jdata, err := json.Marshal(emptyProfile) + if err != nil { + return err + } + io.Copy(pi, bytes.NewBuffer(jdata)) + pi.Close() + + return nil +}