summaryrefslogtreecommitdiffstats
path: root/plugin/rpcplugin/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/rpcplugin/sandbox')
-rw-r--r--plugin/rpcplugin/sandbox/main_test.go18
-rw-r--r--plugin/rpcplugin/sandbox/sandbox.go34
-rw-r--r--plugin/rpcplugin/sandbox/sandbox_linux.go488
-rw-r--r--plugin/rpcplugin/sandbox/sandbox_linux_test.go159
-rw-r--r--plugin/rpcplugin/sandbox/sandbox_other.go22
-rw-r--r--plugin/rpcplugin/sandbox/sandbox_test.go25
-rw-r--r--plugin/rpcplugin/sandbox/seccomp_linux.go178
-rw-r--r--plugin/rpcplugin/sandbox/seccomp_linux_amd64.go301
-rw-r--r--plugin/rpcplugin/sandbox/seccomp_linux_other.go10
-rw-r--r--plugin/rpcplugin/sandbox/seccomp_linux_test.go210
-rw-r--r--plugin/rpcplugin/sandbox/supervisor.go33
-rw-r--r--plugin/rpcplugin/sandbox/supervisor_test.go18
12 files changed, 0 insertions, 1496 deletions
diff --git a/plugin/rpcplugin/sandbox/main_test.go b/plugin/rpcplugin/sandbox/main_test.go
deleted file mode 100644
index 4be4a42af..000000000
--- a/plugin/rpcplugin/sandbox/main_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package sandbox
-
-import (
- "testing"
-
- "github.com/mattermost/mattermost-server/mlog"
-)
-
-func TestMain(t *testing.T) {
- // Setup a global logger to catch tests logging outside of app context
- // The global logger will be stomped by apps initalizing but that's fine for testing. Ideally this won't happen.
- mlog.InitGlobalLogger(mlog.NewLogger(&mlog.LoggerConfiguration{
- EnableConsole: true,
- ConsoleJson: true,
- ConsoleLevel: "error",
- EnableFile: false,
- }))
-}
diff --git a/plugin/rpcplugin/sandbox/sandbox.go b/plugin/rpcplugin/sandbox/sandbox.go
deleted file mode 100644
index 96eff02dd..000000000
--- a/plugin/rpcplugin/sandbox/sandbox.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "context"
- "io"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin"
-)
-
-type MountPoint struct {
- Source string
- Destination string
- Type string
- ReadOnly bool
-}
-
-type Configuration struct {
- MountPoints []*MountPoint
- WorkingDirectory string
-}
-
-// NewProcess is like rpcplugin.NewProcess, but launches the process in a sandbox.
-func NewProcess(ctx context.Context, config *Configuration, path string) (rpcplugin.Process, io.ReadWriteCloser, error) {
- return newProcess(ctx, config, path)
-}
-
-// CheckSupport inspects the platform and environment to determine whether or not there are any
-// expected issues with sandboxing. If nil is returned, sandboxing should be used.
-func CheckSupport() error {
- return checkSupport()
-}
diff --git a/plugin/rpcplugin/sandbox/sandbox_linux.go b/plugin/rpcplugin/sandbox/sandbox_linux.go
deleted file mode 100644
index beb00995d..000000000
--- a/plugin/rpcplugin/sandbox/sandbox_linux.go
+++ /dev/null
@@ -1,488 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "syscall"
- "unsafe"
-
- "github.com/pkg/errors"
- "golang.org/x/sys/unix"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin"
-)
-
-func init() {
- if len(os.Args) < 4 || os.Args[0] != "sandbox.runProcess" {
- return
- }
-
- var config Configuration
- if err := json.Unmarshal([]byte(os.Args[1]), &config); err != nil {
- fmt.Println(err.Error())
- os.Exit(1)
- }
- if err := runProcess(&config, os.Args[2], os.Args[3]); err != nil {
- if eerr, ok := err.(*exec.ExitError); ok {
- if status, ok := eerr.Sys().(syscall.WaitStatus); ok {
- os.Exit(status.ExitStatus())
- }
- }
- fmt.Println(err.Error())
- os.Exit(1)
- }
- os.Exit(0)
-}
-
-func systemMountPoints() (points []*MountPoint) {
- points = append(points, &MountPoint{
- Source: "proc",
- Destination: "/proc",
- Type: "proc",
- }, &MountPoint{
- Source: "/dev/null",
- Destination: "/dev/null",
- }, &MountPoint{
- Source: "/dev/zero",
- Destination: "/dev/zero",
- }, &MountPoint{
- Source: "/dev/full",
- Destination: "/dev/full",
- })
-
- readOnly := []string{
- "/dev/random",
- "/dev/urandom",
- "/etc/resolv.conf",
- "/lib",
- "/lib32",
- "/lib64",
- "/usr/lib",
- "/usr/lib32",
- "/usr/lib64",
- "/etc/ca-certificates",
- "/etc/ssl/certs",
- "/system/etc/security/cacerts",
- "/usr/local/share/certs",
- "/etc/pki/tls/certs",
- "/etc/openssl/certs",
- "/etc/ssl/ca-bundle.pem",
- "/etc/pki/tls/cacert.pem",
- "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
- }
-
- for _, v := range []string{"SSL_CERT_FILE", "SSL_CERT_DIR"} {
- if path := os.Getenv(v); path != "" {
- readOnly = append(readOnly, path)
- }
- }
-
- for _, point := range readOnly {
- points = append(points, &MountPoint{
- Source: point,
- Destination: point,
- ReadOnly: true,
- })
- }
-
- return
-}
-
-func runProcess(config *Configuration, path, root string) error {
- if err := syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
- return errors.Wrapf(err, "unable to make root private")
- }
-
- if err := mountMountPoints(root, systemMountPoints()); err != nil {
- return errors.Wrapf(err, "unable to mount sandbox system mount points")
- }
-
- if err := mountMountPoints(root, config.MountPoints); err != nil {
- return errors.Wrapf(err, "unable to mount sandbox config mount points")
- }
-
- if err := pivotRoot(root); err != nil {
- return errors.Wrapf(err, "unable to pivot sandbox root")
- }
-
- if err := os.Mkdir("/tmp", 0755); err != nil {
- return errors.Wrapf(err, "unable to create /tmp")
- }
-
- if config.WorkingDirectory != "" {
- if err := os.Chdir(config.WorkingDirectory); err != nil {
- return errors.Wrapf(err, "unable to set working directory")
- }
- }
-
- if err := dropInheritableCapabilities(); err != nil {
- return errors.Wrapf(err, "unable to drop inheritable capabilities")
- }
-
- if err := enableSeccompFilter(); err != nil {
- return errors.Wrapf(err, "unable to enable seccomp filter")
- }
-
- return runExecutable(path)
-}
-
-func mountMountPoint(root string, mountPoint *MountPoint) error {
- isDir := true
- if mountPoint.Type == "" {
- stat, err := os.Lstat(mountPoint.Source)
- if err != nil {
- return nil
- }
- if (stat.Mode() & os.ModeSymlink) != 0 {
- if path, err := filepath.EvalSymlinks(mountPoint.Source); err == nil {
- newMountPoint := *mountPoint
- newMountPoint.Source = path
- if err := mountMountPoint(root, &newMountPoint); err != nil {
- return errors.Wrapf(err, "unable to mount symbolic link target: "+mountPoint.Source)
- }
- return nil
- }
- }
- isDir = stat.IsDir()
- }
-
- target := filepath.Join(root, mountPoint.Destination)
-
- if isDir {
- if err := os.MkdirAll(target, 0755); err != nil {
- return errors.Wrapf(err, "unable to create directory: "+target)
- }
- } else {
- if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
- return errors.Wrapf(err, "unable to create directory: "+target)
- }
- f, err := os.Create(target)
- if err != nil {
- return errors.Wrapf(err, "unable to create file: "+target)
- }
- f.Close()
- }
-
- flags := uintptr(syscall.MS_NOSUID | syscall.MS_NODEV)
- if mountPoint.Type == "" {
- flags |= syscall.MS_BIND
- }
- if mountPoint.ReadOnly {
- flags |= syscall.MS_RDONLY
- }
-
- if err := syscall.Mount(mountPoint.Source, target, mountPoint.Type, flags, ""); err != nil {
- return errors.Wrapf(err, "unable to mount "+mountPoint.Source)
- }
-
- if (flags & syscall.MS_BIND) != 0 {
- // If this was a bind mount, our other flags actually got silently ignored during the above syscall:
- //
- // If mountflags includes MS_BIND [...] The remaining bits in the mountflags argument are
- // also ignored, with the exception of MS_REC.
- //
- // Furthermore, remounting will fail if we attempt to unset a bit that was inherited from
- // the mount's parent:
- //
- // The mount(2) flags MS_RDONLY, MS_NOSUID, MS_NOEXEC, and the "atime" flags
- // (MS_NOATIME, MS_NODIRATIME, MS_RELATIME) settings become locked when propagated from
- // a more privileged to a less privileged mount namespace, and may not be changed in the
- // less privileged mount namespace.
- //
- // So we need to get the actual flags, add our new ones, then do a remount if needed.
- var stats syscall.Statfs_t
- if err := syscall.Statfs(target, &stats); err != nil {
- return errors.Wrap(err, "unable to get mount flags for target: "+target)
- }
- const lockedFlagsMask = unix.MS_RDONLY | unix.MS_NOSUID | unix.MS_NOEXEC | unix.MS_NOATIME | unix.MS_NODIRATIME | unix.MS_RELATIME
- lockedFlags := uintptr(stats.Flags & lockedFlagsMask)
- if lockedFlags != ((flags | lockedFlags) & lockedFlagsMask) {
- if err := syscall.Mount("", target, "", flags|lockedFlags|syscall.MS_REMOUNT, ""); err != nil {
- return errors.Wrapf(err, "unable to remount "+mountPoint.Source)
- }
- }
- }
-
- return nil
-}
-
-func mountMountPoints(root string, mountPoints []*MountPoint) error {
- for _, mountPoint := range mountPoints {
- if err := mountMountPoint(root, mountPoint); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func pivotRoot(newRoot string) error {
- if err := syscall.Mount(newRoot, newRoot, "", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
- return errors.Wrapf(err, "unable to mount new root")
- }
-
- prevRoot := filepath.Join(newRoot, ".prev_root")
-
- if err := os.MkdirAll(prevRoot, 0700); err != nil {
- return errors.Wrapf(err, "unable to create directory for previous root")
- }
-
- if err := syscall.PivotRoot(newRoot, prevRoot); err != nil {
- return errors.Wrapf(err, "syscall error")
- }
-
- if err := os.Chdir("/"); err != nil {
- return errors.Wrapf(err, "unable to change directory")
- }
-
- prevRoot = "/.prev_root"
-
- if err := syscall.Unmount(prevRoot, syscall.MNT_DETACH); err != nil {
- return errors.Wrapf(err, "unable to unmount previous root")
- }
-
- if err := os.RemoveAll(prevRoot); err != nil {
- return errors.Wrapf(err, "unable to remove previous root directory")
- }
-
- return nil
-}
-
-func dropInheritableCapabilities() error {
- type capHeader struct {
- version uint32
- pid int32
- }
-
- type capData struct {
- effective uint32
- permitted uint32
- inheritable uint32
- }
-
- var hdr capHeader
- var data [2]capData
-
- if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&hdr)), 0, 0); errno != 0 {
- return errors.Wrapf(syscall.Errno(errno), "unable to get capabilities version")
- }
-
- if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0])), 0); errno != 0 {
- return errors.Wrapf(syscall.Errno(errno), "unable to get capabilities")
- }
-
- data[0].inheritable = 0
- data[1].inheritable = 0
- if _, _, errno := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(&hdr)), uintptr(unsafe.Pointer(&data[0])), 0); errno != 0 {
- return errors.Wrapf(syscall.Errno(errno), "unable to set inheritable capabilities")
- }
-
- for i := 0; i < 64; i++ {
- if _, _, errno := syscall.Syscall(syscall.SYS_PRCTL, syscall.PR_CAPBSET_DROP, uintptr(i), 0); errno != 0 && errno != syscall.EINVAL {
- return errors.Wrapf(syscall.Errno(errno), "unable to drop bounding set capability")
- }
- }
-
- return nil
-}
-
-func enableSeccompFilter() error {
- return EnableSeccompFilter(SeccompFilter(NATIVE_AUDIT_ARCH, AllowedSyscalls))
-}
-
-func runExecutable(path string) error {
- childFiles := []*os.File{
- os.NewFile(3, ""), os.NewFile(4, ""),
- }
- defer childFiles[0].Close()
- defer childFiles[1].Close()
-
- cmd := exec.Command(path)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.ExtraFiles = childFiles
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Pdeathsig: syscall.SIGTERM,
- }
-
- if err := cmd.Run(); err != nil {
- return err
- }
-
- return nil
-}
-
-type process struct {
- command *exec.Cmd
- root string
-}
-
-func newProcess(ctx context.Context, config *Configuration, path string) (pOut rpcplugin.Process, rwcOut io.ReadWriteCloser, errOut error) {
- configJSON, err := json.Marshal(config)
- if err != nil {
- return nil, nil, err
- }
-
- ipc, childFiles, err := rpcplugin.NewIPC()
- if err != nil {
- return nil, nil, err
- }
- defer childFiles[0].Close()
- defer childFiles[1].Close()
-
- root, err := ioutil.TempDir("", "")
- if err != nil {
- return nil, nil, err
- }
- defer func() {
- if errOut != nil {
- os.RemoveAll(root)
- }
- }()
-
- cmd := exec.CommandContext(ctx, "/proc/self/exe")
- cmd.Args = []string{"sandbox.runProcess", string(configJSON), path, root}
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.ExtraFiles = childFiles
-
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWUSER,
- Pdeathsig: syscall.SIGTERM,
- GidMappings: []syscall.SysProcIDMap{
- {
- ContainerID: 0,
- HostID: os.Getgid(),
- Size: 1,
- },
- },
- UidMappings: []syscall.SysProcIDMap{
- {
- ContainerID: 0,
- HostID: os.Getuid(),
- Size: 1,
- },
- },
- }
-
- err = cmd.Start()
- if err != nil {
- ipc.Close()
- return nil, nil, err
- }
-
- return &process{
- command: cmd,
- root: root,
- }, ipc, nil
-}
-
-func (p *process) Wait() error {
- defer os.RemoveAll(p.root)
- return p.command.Wait()
-}
-
-func init() {
- if len(os.Args) < 2 || os.Args[0] != "sandbox.checkSupportInNamespace" {
- return
- }
-
- if err := checkSupportInNamespace(os.Args[1]); err != nil {
- fmt.Fprintf(os.Stderr, "%v", err.Error())
- os.Exit(1)
- }
-
- os.Exit(0)
-}
-
-func checkSupportInNamespace(root string) error {
- if err := syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
- return errors.Wrapf(err, "unable to make root private")
- }
-
- if err := mountMountPoints(root, systemMountPoints()); err != nil {
- return errors.Wrapf(err, "unable to mount sandbox system mount points")
- }
-
- if err := pivotRoot(root); err != nil {
- return errors.Wrapf(err, "unable to pivot sandbox root")
- }
-
- if err := dropInheritableCapabilities(); err != nil {
- return errors.Wrapf(err, "unable to drop inheritable capabilities")
- }
-
- if err := enableSeccompFilter(); err != nil {
- return errors.Wrapf(err, "unable to enable seccomp filter")
- }
-
- if f, err := os.Create(os.DevNull); err != nil {
- return errors.Wrapf(err, "unable to open os.DevNull")
- } else {
- defer f.Close()
- if _, err = f.Write([]byte("foo")); err != nil {
- return errors.Wrapf(err, "unable to write to os.DevNull")
- }
- }
-
- return nil
-}
-
-func checkSupport() error {
- if AllowedSyscalls == nil {
- return fmt.Errorf("unsupported architecture")
- }
-
- stderr := &bytes.Buffer{}
-
- root, err := ioutil.TempDir("", "")
- if err != nil {
- return err
- }
- defer os.RemoveAll(root)
-
- cmd := exec.Command("/proc/self/exe")
- cmd.Args = []string{"sandbox.checkSupportInNamespace", root}
- cmd.Stderr = stderr
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWUSER,
- Pdeathsig: syscall.SIGTERM,
- GidMappings: []syscall.SysProcIDMap{
- {
- ContainerID: 0,
- HostID: os.Getgid(),
- Size: 1,
- },
- },
- UidMappings: []syscall.SysProcIDMap{
- {
- ContainerID: 0,
- HostID: os.Getuid(),
- Size: 1,
- },
- },
- }
-
- if err := cmd.Start(); err != nil {
- return errors.Wrapf(err, "unable to create user namespace")
- }
-
- if err := cmd.Wait(); err != nil {
- if _, ok := err.(*exec.ExitError); ok {
- return errors.Wrapf(fmt.Errorf("%v", stderr.String()), "unable to prepare namespace")
- }
- return errors.Wrapf(err, "unable to prepare namespace")
- }
-
- return nil
-}
diff --git a/plugin/rpcplugin/sandbox/sandbox_linux_test.go b/plugin/rpcplugin/sandbox/sandbox_linux_test.go
deleted file mode 100644
index 2bcbf0c57..000000000
--- a/plugin/rpcplugin/sandbox/sandbox_linux_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "context"
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin/rpcplugintest"
-)
-
-func TestNewProcess(t *testing.T) {
- if err := CheckSupport(); err != nil {
- t.Skip("sandboxing not supported:", err)
- }
-
- dir, err := ioutil.TempDir("", "")
- require.NoError(t, err)
- defer os.RemoveAll(dir)
-
- ping := filepath.Join(dir, "ping.exe")
- rpcplugintest.CompileGo(t, `
- package main
-
- import (
- "crypto/rand"
- "fmt"
- "io/ioutil"
- "net/http"
- "os"
- "os/exec"
- "syscall"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin"
- )
-
- var failures int
-
- type T struct {}
- func (T) Errorf(format string, args ...interface{}) {
- fmt.Printf(format, args...)
- failures++
- }
- func (T) FailNow() {
- os.Exit(1)
- }
-
- func init() {
- if len(os.Args) > 0 && os.Args[0] == "exitImmediately" {
- os.Exit(0)
- }
- }
-
- func main() {
- t := &T{}
-
- pwd, err := os.Getwd()
- assert.NoError(t, err)
- assert.Equal(t, "/dir", pwd)
-
- assert.Equal(t, 0, os.Getgid(), "we should see ourselves as root")
- assert.Equal(t, 0, os.Getuid(), "we should see ourselves as root")
-
- f, err := ioutil.TempFile("", "")
- require.NoError(t, err, "we should be able to create temporary files")
- f.Close()
-
- _, err = os.Stat("ping.exe")
- assert.NoError(t, err, "we should be able to read files in the working directory")
-
- buf := make([]byte, 20)
- n, err := rand.Read(buf)
- assert.Equal(t, 20, n)
- assert.NoError(t, err, "we should be able to read from /dev/urandom")
-
- f, err = os.Create("/dev/zero")
- require.NoError(t, err, "we should be able to write to /dev/zero")
- defer f.Close()
- n, err = f.Write([]byte("foo"))
- assert.Equal(t, 3, n)
- require.NoError(t, err, "we should be able to write to /dev/zero")
-
- f, err = os.Create("/dir/foo")
- if f != nil {
- defer f.Close()
- }
- assert.Error(t, err, "we shouldn't be able to write to this read-only mount point")
-
- _, err = ioutil.ReadFile("/etc/resolv.conf")
- require.NoError(t, err, "we should be able to read /etc/resolv.conf")
-
- resp, err := http.Get("https://github.com")
- require.NoError(t, err, "we should be able to use the network")
- resp.Body.Close()
-
- status, err := ioutil.ReadFile("/proc/self/status")
- require.NoError(t, err, "we should be able to read from /proc")
- assert.Regexp(t, status, "CapEff:\\s+0000000000000000", "we should have no effective capabilities")
-
- require.NoError(t, os.MkdirAll("/tmp/dir2", 0755))
- err = syscall.Mount("/dir", "/tmp/dir2", "", syscall.MS_BIND, "")
- assert.Equal(t, syscall.EPERM, err, "we shouldn't be allowed to mount things")
-
- cmd := exec.Command("/proc/self/exe")
- cmd.Args = []string{"exitImmediately"}
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Pdeathsig: syscall.SIGTERM,
- }
- assert.NoError(t, cmd.Run(), "we should be able to re-exec ourself")
-
- cmd = exec.Command("/proc/self/exe")
- cmd.Args = []string{"exitImmediately"}
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWUSER,
- Pdeathsig: syscall.SIGTERM,
- }
- assert.Error(t, cmd.Run(), "we shouldn't be able to create new namespaces anymore")
-
- ipc, err := rpcplugin.InheritedProcessIPC()
- require.NoError(t, err)
- defer ipc.Close()
- _, err = ipc.Write([]byte("ping"))
- require.NoError(t, err)
-
- if failures > 0 {
- os.Exit(1)
- }
- }
- `, ping)
-
- p, ipc, err := NewProcess(context.Background(), &Configuration{
- MountPoints: []*MountPoint{
- {
- Source: dir,
- Destination: "/dir",
- ReadOnly: true,
- },
- },
- WorkingDirectory: "/dir",
- }, "/dir/ping.exe")
- require.NoError(t, err)
- defer ipc.Close()
- b := make([]byte, 10)
- n, err := ipc.Read(b)
- require.NoError(t, err)
- assert.Equal(t, 4, n)
- assert.Equal(t, "ping", string(b[:4]))
- require.NoError(t, p.Wait())
-}
diff --git a/plugin/rpcplugin/sandbox/sandbox_other.go b/plugin/rpcplugin/sandbox/sandbox_other.go
deleted file mode 100644
index 3889ecdcc..000000000
--- a/plugin/rpcplugin/sandbox/sandbox_other.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-// +build !linux
-
-package sandbox
-
-import (
- "context"
- "fmt"
- "io"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin"
-)
-
-func newProcess(ctx context.Context, config *Configuration, path string) (rpcplugin.Process, io.ReadWriteCloser, error) {
- return nil, nil, checkSupport()
-}
-
-func checkSupport() error {
- return fmt.Errorf("sandboxing is not supported on this platform")
-}
diff --git a/plugin/rpcplugin/sandbox/sandbox_test.go b/plugin/rpcplugin/sandbox/sandbox_test.go
deleted file mode 100644
index e0149e28d..000000000
--- a/plugin/rpcplugin/sandbox/sandbox_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "testing"
-)
-
-// TestCheckSupport is here for debugging purposes and has no assertions. You can quickly test
-// sandboxing support with various systems by compiling the test executable and running this test on
-// your target systems. For example, with docker, executed from the root of the repo:
-//
-// docker run --rm -it -w /go/src/github.com/mattermost/mattermost-server
-// -v $(pwd):/go/src/github.com/mattermost/mattermost-server golang:1.9
-// go test -c ./plugin/rpcplugin
-//
-// docker run --rm -it --privileged -w /opt/mattermost
-// -v $(pwd):/opt/mattermost centos:6
-// ./rpcplugin.test --test.v --test.run TestCheckSupport
-func TestCheckSupport(t *testing.T) {
- if err := CheckSupport(); err != nil {
- t.Log(err.Error())
- }
-}
diff --git a/plugin/rpcplugin/sandbox/seccomp_linux.go b/plugin/rpcplugin/sandbox/seccomp_linux.go
deleted file mode 100644
index afe86e90a..000000000
--- a/plugin/rpcplugin/sandbox/seccomp_linux.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "syscall"
- "unsafe"
-
- "github.com/pkg/errors"
- "golang.org/x/net/bpf"
- "golang.org/x/sys/unix"
-)
-
-const (
- SECCOMP_RET_ALLOW = 0x7fff0000
- SECCOMP_RET_ERRNO = 0x00050000
-)
-
-const (
- EM_X86_64 = 62
-
- __AUDIT_ARCH_64BIT = 0x80000000
- __AUDIT_ARCH_LE = 0x40000000
-
- AUDIT_ARCH_X86_64 = EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE
-
- nrSize = 4
- archOffset = nrSize
- ipOffset = archOffset + 4
- argsOffset = ipOffset + 8
-)
-
-type SeccompCondition interface {
- Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction
-}
-
-func seccompArgLowWord(arg int, littleEndian bool) uint32 {
- offset := uint32(argsOffset + arg*8)
- if !littleEndian {
- offset += 4
- }
- return offset
-}
-
-func seccompArgHighWord(arg int, littleEndian bool) uint32 {
- offset := uint32(argsOffset + arg*8)
- if littleEndian {
- offset += 4
- }
- return offset
-}
-
-type SeccompArgHasNoBits struct {
- Arg int
- Mask uint64
-}
-
-func (c SeccompArgHasNoBits) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask >> 32), SkipTrue: skipFalseSentinel},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask), SkipTrue: skipFalseSentinel},
- }
-}
-
-type SeccompArgHasAnyBit struct {
- Arg int
- Mask uint64
-}
-
-func (c SeccompArgHasAnyBit) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask >> 32), SkipTrue: 2},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: uint32(c.Mask), SkipFalse: skipFalseSentinel},
- }
-}
-
-type SeccompArgEquals struct {
- Arg int
- Value uint64
-}
-
-func (c SeccompArgEquals) Filter(littleEndian bool, skipFalseSentinel uint8) []bpf.Instruction {
- return []bpf.Instruction{
- bpf.LoadAbsolute{Off: seccompArgHighWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(c.Value >> 32), SkipFalse: skipFalseSentinel},
- bpf.LoadAbsolute{Off: seccompArgLowWord(c.Arg, littleEndian), Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(c.Value), SkipFalse: skipFalseSentinel},
- }
-}
-
-type SeccompConditions struct {
- All []SeccompCondition
-}
-
-type SeccompSyscall struct {
- Syscall uint32
- Any []SeccompConditions
-}
-
-func SeccompFilter(arch uint32, allowedSyscalls []SeccompSyscall) (filter []bpf.Instruction) {
- filter = append(filter,
- bpf.LoadAbsolute{Off: archOffset, Size: 4},
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: arch, SkipTrue: 1},
- bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)},
- )
-
- filter = append(filter, bpf.LoadAbsolute{Off: 0, Size: nrSize})
- for _, s := range allowedSyscalls {
- if s.Any != nil {
- syscallStart := len(filter)
- filter = append(filter, bpf.Instruction(nil))
- for _, cs := range s.Any {
- anyStart := len(filter)
- for _, c := range cs.All {
- filter = append(filter, c.Filter((arch&__AUDIT_ARCH_LE) != 0, 255)...)
- }
- filter = append(filter, bpf.RetConstant{Val: SECCOMP_RET_ALLOW})
- for i := anyStart; i < len(filter); i++ {
- if jump, ok := filter[i].(bpf.JumpIf); ok {
- if len(filter)-i-1 > 255 {
- panic("condition too long")
- }
- if jump.SkipFalse == 255 {
- jump.SkipFalse = uint8(len(filter) - i - 1)
- }
- if jump.SkipTrue == 255 {
- jump.SkipTrue = uint8(len(filter) - i - 1)
- }
- filter[i] = jump
- }
- }
- }
- filter = append(filter, bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)})
- if len(filter)-syscallStart-1 > 255 {
- panic("conditions too long")
- }
- filter[syscallStart] = bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(s.Syscall), SkipFalse: uint8(len(filter) - syscallStart - 1)}
- } else {
- filter = append(filter,
- bpf.JumpIf{Cond: bpf.JumpEqual, Val: uint32(s.Syscall), SkipFalse: 1},
- bpf.RetConstant{Val: SECCOMP_RET_ALLOW},
- )
- }
- }
-
- return append(filter, bpf.RetConstant{Val: uint32(SECCOMP_RET_ERRNO | unix.EPERM)})
-}
-
-func EnableSeccompFilter(filter []bpf.Instruction) error {
- assembled, err := bpf.Assemble(filter)
- if err != nil {
- return errors.Wrapf(err, "unable to assemble filter")
- }
-
- sockFilter := make([]unix.SockFilter, len(filter))
- for i, instruction := range assembled {
- sockFilter[i].Code = instruction.Op
- sockFilter[i].Jt = instruction.Jt
- sockFilter[i].Jf = instruction.Jf
- sockFilter[i].K = instruction.K
- }
-
- prog := unix.SockFprog{
- Len: uint16(len(sockFilter)),
- Filter: &sockFilter[0],
- }
-
- if _, _, errno := syscall.Syscall(syscall.SYS_PRCTL, unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, uintptr(unsafe.Pointer(&prog))); errno != 0 {
- return errors.Wrapf(syscall.Errno(errno), "syscall error")
- }
-
- return nil
-}
diff --git a/plugin/rpcplugin/sandbox/seccomp_linux_amd64.go b/plugin/rpcplugin/sandbox/seccomp_linux_amd64.go
deleted file mode 100644
index 7338ebbe0..000000000
--- a/plugin/rpcplugin/sandbox/seccomp_linux_amd64.go
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "golang.org/x/sys/unix"
-)
-
-const NATIVE_AUDIT_ARCH = AUDIT_ARCH_X86_64
-
-var AllowedSyscalls = []SeccompSyscall{
- {Syscall: unix.SYS_ACCEPT},
- {Syscall: unix.SYS_ACCEPT4},
- {Syscall: unix.SYS_ACCESS},
- {Syscall: unix.SYS_ADJTIMEX},
- {Syscall: unix.SYS_ALARM},
- {Syscall: unix.SYS_ARCH_PRCTL},
- {Syscall: unix.SYS_BIND},
- {Syscall: unix.SYS_BRK},
- {Syscall: unix.SYS_CAPGET},
- {Syscall: unix.SYS_CAPSET},
- {Syscall: unix.SYS_CHDIR},
- {Syscall: unix.SYS_CHMOD},
- {Syscall: unix.SYS_CHOWN},
- {Syscall: unix.SYS_CLOCK_GETRES},
- {Syscall: unix.SYS_CLOCK_GETTIME},
- {Syscall: unix.SYS_CLOCK_NANOSLEEP},
- {
- Syscall: unix.SYS_CLONE,
- Any: []SeccompConditions{{
- All: []SeccompCondition{SeccompArgHasNoBits{
- Arg: 0,
- Mask: unix.CLONE_NEWCGROUP | unix.CLONE_NEWIPC | unix.CLONE_NEWNET | unix.CLONE_NEWNS | unix.CLONE_NEWPID | unix.CLONE_NEWUSER | unix.CLONE_NEWUTS,
- }},
- }},
- },
- {Syscall: unix.SYS_CLOSE},
- {Syscall: unix.SYS_CONNECT},
- {Syscall: unix.SYS_COPY_FILE_RANGE},
- {Syscall: unix.SYS_CREAT},
- {Syscall: unix.SYS_DUP},
- {Syscall: unix.SYS_DUP2},
- {Syscall: unix.SYS_DUP3},
- {Syscall: unix.SYS_EPOLL_CREATE},
- {Syscall: unix.SYS_EPOLL_CREATE1},
- {Syscall: unix.SYS_EPOLL_CTL},
- {Syscall: unix.SYS_EPOLL_CTL_OLD},
- {Syscall: unix.SYS_EPOLL_PWAIT},
- {Syscall: unix.SYS_EPOLL_WAIT},
- {Syscall: unix.SYS_EPOLL_WAIT_OLD},
- {Syscall: unix.SYS_EVENTFD},
- {Syscall: unix.SYS_EVENTFD2},
- {Syscall: unix.SYS_EXECVE},
- {Syscall: unix.SYS_EXECVEAT},
- {Syscall: unix.SYS_EXIT},
- {Syscall: unix.SYS_EXIT_GROUP},
- {Syscall: unix.SYS_FACCESSAT},
- {Syscall: unix.SYS_FADVISE64},
- {Syscall: unix.SYS_FALLOCATE},
- {Syscall: unix.SYS_FANOTIFY_MARK},
- {Syscall: unix.SYS_FCHDIR},
- {Syscall: unix.SYS_FCHMOD},
- {Syscall: unix.SYS_FCHMODAT},
- {Syscall: unix.SYS_FCHOWN},
- {Syscall: unix.SYS_FCHOWNAT},
- {Syscall: unix.SYS_FCNTL},
- {Syscall: unix.SYS_FDATASYNC},
- {Syscall: unix.SYS_FGETXATTR},
- {Syscall: unix.SYS_FLISTXATTR},
- {Syscall: unix.SYS_FLOCK},
- {Syscall: unix.SYS_FORK},
- {Syscall: unix.SYS_FREMOVEXATTR},
- {Syscall: unix.SYS_FSETXATTR},
- {Syscall: unix.SYS_FSTAT},
- {Syscall: unix.SYS_FSTATFS},
- {Syscall: unix.SYS_FSYNC},
- {Syscall: unix.SYS_FTRUNCATE},
- {Syscall: unix.SYS_FUTEX},
- {Syscall: unix.SYS_FUTIMESAT},
- {Syscall: unix.SYS_GETCPU},
- {Syscall: unix.SYS_GETCWD},
- {Syscall: unix.SYS_GETDENTS},
- {Syscall: unix.SYS_GETDENTS64},
- {Syscall: unix.SYS_GETEGID},
- {Syscall: unix.SYS_GETEUID},
- {Syscall: unix.SYS_GETGID},
- {Syscall: unix.SYS_GETGROUPS},
- {Syscall: unix.SYS_GETITIMER},
- {Syscall: unix.SYS_GETPEERNAME},
- {Syscall: unix.SYS_GETPGID},
- {Syscall: unix.SYS_GETPGRP},
- {Syscall: unix.SYS_GETPID},
- {Syscall: unix.SYS_GETPPID},
- {Syscall: unix.SYS_GETPRIORITY},
- {Syscall: unix.SYS_GETRANDOM},
- {Syscall: unix.SYS_GETRESGID},
- {Syscall: unix.SYS_GETRESUID},
- {Syscall: unix.SYS_GETRLIMIT},
- {Syscall: unix.SYS_GET_ROBUST_LIST},
- {Syscall: unix.SYS_GETRUSAGE},
- {Syscall: unix.SYS_GETSID},
- {Syscall: unix.SYS_GETSOCKNAME},
- {Syscall: unix.SYS_GETSOCKOPT},
- {Syscall: unix.SYS_GET_THREAD_AREA},
- {Syscall: unix.SYS_GETTID},
- {Syscall: unix.SYS_GETTIMEOFDAY},
- {Syscall: unix.SYS_GETUID},
- {Syscall: unix.SYS_GETXATTR},
- {Syscall: unix.SYS_INOTIFY_ADD_WATCH},
- {Syscall: unix.SYS_INOTIFY_INIT},
- {Syscall: unix.SYS_INOTIFY_INIT1},
- {Syscall: unix.SYS_INOTIFY_RM_WATCH},
- {Syscall: unix.SYS_IO_CANCEL},
- {Syscall: unix.SYS_IOCTL},
- {Syscall: unix.SYS_IO_DESTROY},
- {Syscall: unix.SYS_IO_GETEVENTS},
- {Syscall: unix.SYS_IOPRIO_GET},
- {Syscall: unix.SYS_IOPRIO_SET},
- {Syscall: unix.SYS_IO_SETUP},
- {Syscall: unix.SYS_IO_SUBMIT},
- {Syscall: unix.SYS_KILL},
- {Syscall: unix.SYS_LCHOWN},
- {Syscall: unix.SYS_LGETXATTR},
- {Syscall: unix.SYS_LINK},
- {Syscall: unix.SYS_LINKAT},
- {Syscall: unix.SYS_LISTEN},
- {Syscall: unix.SYS_LISTXATTR},
- {Syscall: unix.SYS_LLISTXATTR},
- {Syscall: unix.SYS_LREMOVEXATTR},
- {Syscall: unix.SYS_LSEEK},
- {Syscall: unix.SYS_LSETXATTR},
- {Syscall: unix.SYS_LSTAT},
- {Syscall: unix.SYS_MADVISE},
- {Syscall: unix.SYS_MEMFD_CREATE},
- {Syscall: unix.SYS_MINCORE},
- {Syscall: unix.SYS_MKDIR},
- {Syscall: unix.SYS_MKDIRAT},
- {Syscall: unix.SYS_MKNOD},
- {Syscall: unix.SYS_MKNODAT},
- {Syscall: unix.SYS_MLOCK},
- {Syscall: unix.SYS_MLOCK2},
- {Syscall: unix.SYS_MLOCKALL},
- {Syscall: unix.SYS_MMAP},
- {Syscall: unix.SYS_MODIFY_LDT},
- {Syscall: unix.SYS_MPROTECT},
- {Syscall: unix.SYS_MQ_GETSETATTR},
- {Syscall: unix.SYS_MQ_NOTIFY},
- {Syscall: unix.SYS_MQ_OPEN},
- {Syscall: unix.SYS_MQ_TIMEDRECEIVE},
- {Syscall: unix.SYS_MQ_TIMEDSEND},
- {Syscall: unix.SYS_MQ_UNLINK},
- {Syscall: unix.SYS_MREMAP},
- {Syscall: unix.SYS_MSGCTL},
- {Syscall: unix.SYS_MSGGET},
- {Syscall: unix.SYS_MSGRCV},
- {Syscall: unix.SYS_MSGSND},
- {Syscall: unix.SYS_MSYNC},
- {Syscall: unix.SYS_MUNLOCK},
- {Syscall: unix.SYS_MUNLOCKALL},
- {Syscall: unix.SYS_MUNMAP},
- {Syscall: unix.SYS_NANOSLEEP},
- {Syscall: unix.SYS_NEWFSTATAT},
- {Syscall: unix.SYS_OPEN},
- {Syscall: unix.SYS_OPENAT},
- {Syscall: unix.SYS_PAUSE},
- {
- Syscall: unix.SYS_PERSONALITY,
- Any: []SeccompConditions{
- {All: []SeccompCondition{SeccompArgEquals{Arg: 0, Value: 0}}},
- {All: []SeccompCondition{SeccompArgEquals{Arg: 0, Value: 8}}},
- {All: []SeccompCondition{SeccompArgEquals{Arg: 0, Value: 0x20000}}},
- {All: []SeccompCondition{SeccompArgEquals{Arg: 0, Value: 0x20008}}},
- {All: []SeccompCondition{SeccompArgEquals{Arg: 0, Value: 0xffffffff}}},
- },
- },
- {Syscall: unix.SYS_PIPE},
- {Syscall: unix.SYS_PIPE2},
- {Syscall: unix.SYS_POLL},
- {Syscall: unix.SYS_PPOLL},
- {Syscall: unix.SYS_PRCTL},
- {Syscall: unix.SYS_PREAD64},
- {Syscall: unix.SYS_PREADV},
- {Syscall: unix.SYS_PREADV2},
- {Syscall: unix.SYS_PRLIMIT64},
- {Syscall: unix.SYS_PSELECT6},
- {Syscall: unix.SYS_PWRITE64},
- {Syscall: unix.SYS_PWRITEV},
- {Syscall: unix.SYS_PWRITEV2},
- {Syscall: unix.SYS_READ},
- {Syscall: unix.SYS_READAHEAD},
- {Syscall: unix.SYS_READLINK},
- {Syscall: unix.SYS_READLINKAT},
- {Syscall: unix.SYS_READV},
- {Syscall: unix.SYS_RECVFROM},
- {Syscall: unix.SYS_RECVMMSG},
- {Syscall: unix.SYS_RECVMSG},
- {Syscall: unix.SYS_REMAP_FILE_PAGES},
- {Syscall: unix.SYS_REMOVEXATTR},
- {Syscall: unix.SYS_RENAME},
- {Syscall: unix.SYS_RENAMEAT},
- {Syscall: unix.SYS_RENAMEAT2},
- {Syscall: unix.SYS_RESTART_SYSCALL},
- {Syscall: unix.SYS_RMDIR},
- {Syscall: unix.SYS_RT_SIGACTION},
- {Syscall: unix.SYS_RT_SIGPENDING},
- {Syscall: unix.SYS_RT_SIGPROCMASK},
- {Syscall: unix.SYS_RT_SIGQUEUEINFO},
- {Syscall: unix.SYS_RT_SIGRETURN},
- {Syscall: unix.SYS_RT_SIGSUSPEND},
- {Syscall: unix.SYS_RT_SIGTIMEDWAIT},
- {Syscall: unix.SYS_RT_TGSIGQUEUEINFO},
- {Syscall: unix.SYS_SCHED_GETAFFINITY},
- {Syscall: unix.SYS_SCHED_GETATTR},
- {Syscall: unix.SYS_SCHED_GETPARAM},
- {Syscall: unix.SYS_SCHED_GET_PRIORITY_MAX},
- {Syscall: unix.SYS_SCHED_GET_PRIORITY_MIN},
- {Syscall: unix.SYS_SCHED_GETSCHEDULER},
- {Syscall: unix.SYS_SCHED_RR_GET_INTERVAL},
- {Syscall: unix.SYS_SCHED_SETAFFINITY},
- {Syscall: unix.SYS_SCHED_SETATTR},
- {Syscall: unix.SYS_SCHED_SETPARAM},
- {Syscall: unix.SYS_SCHED_SETSCHEDULER},
- {Syscall: unix.SYS_SCHED_YIELD},
- {Syscall: unix.SYS_SECCOMP},
- {Syscall: unix.SYS_SELECT},
- {Syscall: unix.SYS_SEMCTL},
- {Syscall: unix.SYS_SEMGET},
- {Syscall: unix.SYS_SEMOP},
- {Syscall: unix.SYS_SEMTIMEDOP},
- {Syscall: unix.SYS_SENDFILE},
- {Syscall: unix.SYS_SENDMMSG},
- {Syscall: unix.SYS_SENDMSG},
- {Syscall: unix.SYS_SENDTO},
- {Syscall: unix.SYS_SETFSGID},
- {Syscall: unix.SYS_SETFSUID},
- {Syscall: unix.SYS_SETGID},
- {Syscall: unix.SYS_SETGROUPS},
- {Syscall: unix.SYS_SETITIMER},
- {Syscall: unix.SYS_SETPGID},
- {Syscall: unix.SYS_SETPRIORITY},
- {Syscall: unix.SYS_SETREGID},
- {Syscall: unix.SYS_SETRESGID},
- {Syscall: unix.SYS_SETRESUID},
- {Syscall: unix.SYS_SETREUID},
- {Syscall: unix.SYS_SETRLIMIT},
- {Syscall: unix.SYS_SET_ROBUST_LIST},
- {Syscall: unix.SYS_SETSID},
- {Syscall: unix.SYS_SETSOCKOPT},
- {Syscall: unix.SYS_SET_THREAD_AREA},
- {Syscall: unix.SYS_SET_TID_ADDRESS},
- {Syscall: unix.SYS_SETUID},
- {Syscall: unix.SYS_SETXATTR},
- {Syscall: unix.SYS_SHMAT},
- {Syscall: unix.SYS_SHMCTL},
- {Syscall: unix.SYS_SHMDT},
- {Syscall: unix.SYS_SHMGET},
- {Syscall: unix.SYS_SHUTDOWN},
- {Syscall: unix.SYS_SIGALTSTACK},
- {Syscall: unix.SYS_SIGNALFD},
- {Syscall: unix.SYS_SIGNALFD4},
- {Syscall: unix.SYS_SOCKET},
- {Syscall: unix.SYS_SOCKETPAIR},
- {Syscall: unix.SYS_SPLICE},
- {Syscall: unix.SYS_STAT},
- {Syscall: unix.SYS_STATFS},
- {Syscall: unix.SYS_SYMLINK},
- {Syscall: unix.SYS_SYMLINKAT},
- {Syscall: unix.SYS_SYNC},
- {Syscall: unix.SYS_SYNC_FILE_RANGE},
- {Syscall: unix.SYS_SYNCFS},
- {Syscall: unix.SYS_SYSINFO},
- {Syscall: unix.SYS_SYSLOG},
- {Syscall: unix.SYS_TEE},
- {Syscall: unix.SYS_TGKILL},
- {Syscall: unix.SYS_TIME},
- {Syscall: unix.SYS_TIMER_CREATE},
- {Syscall: unix.SYS_TIMER_DELETE},
- {Syscall: unix.SYS_TIMERFD_CREATE},
- {Syscall: unix.SYS_TIMERFD_GETTIME},
- {Syscall: unix.SYS_TIMERFD_SETTIME},
- {Syscall: unix.SYS_TIMER_GETOVERRUN},
- {Syscall: unix.SYS_TIMER_GETTIME},
- {Syscall: unix.SYS_TIMER_SETTIME},
- {Syscall: unix.SYS_TIMES},
- {Syscall: unix.SYS_TKILL},
- {Syscall: unix.SYS_TRUNCATE},
- {Syscall: unix.SYS_UMASK},
- {Syscall: unix.SYS_UNAME},
- {Syscall: unix.SYS_UNLINK},
- {Syscall: unix.SYS_UNLINKAT},
- {Syscall: unix.SYS_UTIME},
- {Syscall: unix.SYS_UTIMENSAT},
- {Syscall: unix.SYS_UTIMES},
- {Syscall: unix.SYS_VFORK},
- {Syscall: unix.SYS_VMSPLICE},
- {Syscall: unix.SYS_WAIT4},
- {Syscall: unix.SYS_WAITID},
- {Syscall: unix.SYS_WRITE},
- {Syscall: unix.SYS_WRITEV},
-}
diff --git a/plugin/rpcplugin/sandbox/seccomp_linux_other.go b/plugin/rpcplugin/sandbox/seccomp_linux_other.go
deleted file mode 100644
index 5573943cd..000000000
--- a/plugin/rpcplugin/sandbox/seccomp_linux_other.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-// +build linux,!amd64
-
-package sandbox
-
-const NATIVE_AUDIT_ARCH = 0
-
-var AllowedSyscalls []SeccompSyscall
diff --git a/plugin/rpcplugin/sandbox/seccomp_linux_test.go b/plugin/rpcplugin/sandbox/seccomp_linux_test.go
deleted file mode 100644
index 46fe38fe0..000000000
--- a/plugin/rpcplugin/sandbox/seccomp_linux_test.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "encoding/binary"
- "syscall"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "golang.org/x/net/bpf"
-)
-
-func seccompData(nr int32, arch uint32, ip uint64, args ...uint64) []byte {
- var buf [64]byte
- binary.BigEndian.PutUint32(buf[0:], uint32(nr))
- binary.BigEndian.PutUint32(buf[4:], arch)
- binary.BigEndian.PutUint64(buf[8:], ip)
- for i := 0; i < 6 && i < len(args); i++ {
- binary.BigEndian.PutUint64(buf[16+i*8:], args[i])
- }
- return buf[:]
-}
-
-func TestSeccompFilter(t *testing.T) {
- for name, tc := range map[string]struct {
- Filter []bpf.Instruction
- Data []byte
- Expected bool
- }{
- "Allowed": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {Syscall: syscall.SYS_READ},
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_READ, 0xf00, 0),
- Expected: true,
- },
- "AllFail": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {
- Syscall: syscall.SYS_READ,
- Any: []SeccompConditions{
- {All: []SeccompCondition{
- &SeccompArgHasAnyBit{Arg: 0, Mask: 2},
- &SeccompArgHasAnyBit{Arg: 1, Mask: 2},
- &SeccompArgHasAnyBit{Arg: 2, Mask: 2},
- &SeccompArgHasAnyBit{Arg: 3, Mask: 2},
- }},
- },
- },
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_READ, 0xf00, 0, 1, 2, 3, 4),
- Expected: false,
- },
- "AllPass": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {
- Syscall: syscall.SYS_READ,
- Any: []SeccompConditions{
- {All: []SeccompCondition{
- &SeccompArgHasAnyBit{Arg: 0, Mask: 7},
- &SeccompArgHasAnyBit{Arg: 1, Mask: 7},
- &SeccompArgHasAnyBit{Arg: 2, Mask: 7},
- &SeccompArgHasAnyBit{Arg: 3, Mask: 7},
- }},
- },
- },
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_READ, 0xf00, 0, 1, 2, 3, 4),
- Expected: true,
- },
- "AnyFail": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {
- Syscall: syscall.SYS_READ,
- Any: []SeccompConditions{
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 0, Mask: 8}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 1, Mask: 8}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 2, Mask: 8}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 3, Mask: 8}}},
- },
- },
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_READ, 0xf00, 0, 1, 2, 3, 4),
- Expected: false,
- },
- "AnyPass": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {
- Syscall: syscall.SYS_READ,
- Any: []SeccompConditions{
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 0, Mask: 2}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 1, Mask: 2}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 2, Mask: 2}}},
- {All: []SeccompCondition{&SeccompArgHasAnyBit{Arg: 3, Mask: 2}}},
- },
- },
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_READ, 0xf00, 0, 1, 2, 3, 4),
- Expected: true,
- },
- "BadArch": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {Syscall: syscall.SYS_READ},
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_MOUNT, 0xf01, 0),
- Expected: false,
- },
- "BadSyscall": {
- Filter: SeccompFilter(0xf00, []SeccompSyscall{
- {Syscall: syscall.SYS_READ},
- {Syscall: syscall.SYS_WRITE},
- }),
- Data: seccompData(syscall.SYS_MOUNT, 0xf00, 0),
- Expected: false,
- },
- } {
- t.Run(name, func(t *testing.T) {
- vm, err := bpf.NewVM(tc.Filter)
- require.NoError(t, err)
- result, err := vm.Run(tc.Data)
- require.NoError(t, err)
- if tc.Expected {
- assert.Equal(t, SECCOMP_RET_ALLOW, result)
- } else {
- assert.Equal(t, int(SECCOMP_RET_ERRNO|syscall.EPERM), result)
- }
- })
- }
-}
-
-func TestSeccompFilter_Conditions(t *testing.T) {
- for name, tc := range map[string]struct {
- Condition SeccompCondition
- Args []uint64
- Expected bool
- }{
- "ArgHasAnyBitFail": {
- Condition: SeccompArgHasAnyBit{Arg: 0, Mask: 0x0004},
- Args: []uint64{0x0400008000},
- Expected: false,
- },
- "ArgHasAnyBitPass1": {
- Condition: SeccompArgHasAnyBit{Arg: 0, Mask: 0x400000004},
- Args: []uint64{0x8000008004},
- Expected: true,
- },
- "ArgHasAnyBitPass2": {
- Condition: SeccompArgHasAnyBit{Arg: 0, Mask: 0x400000004},
- Args: []uint64{0x8400008000},
- Expected: true,
- },
- "ArgHasNoBitsFail1": {
- Condition: SeccompArgHasNoBits{Arg: 0, Mask: 0x1100000011},
- Args: []uint64{0x0000008007},
- Expected: false,
- },
- "ArgHasNoBitsFail2": {
- Condition: SeccompArgHasNoBits{Arg: 0, Mask: 0x1100000011},
- Args: []uint64{0x0700008000},
- Expected: false,
- },
- "ArgHasNoBitsPass": {
- Condition: SeccompArgHasNoBits{Arg: 0, Mask: 0x400000004},
- Args: []uint64{0x8000008000},
- Expected: true,
- },
- "ArgEqualsPass": {
- Condition: SeccompArgEquals{Arg: 0, Value: 0x123456789ABCDEF},
- Args: []uint64{0x123456789ABCDEF},
- Expected: true,
- },
- "ArgEqualsFail1": {
- Condition: SeccompArgEquals{Arg: 0, Value: 0x123456789ABCDEF},
- Args: []uint64{0x023456789ABCDEF},
- Expected: false,
- },
- "ArgEqualsFail2": {
- Condition: SeccompArgEquals{Arg: 0, Value: 0x123456789ABCDEF},
- Args: []uint64{0x123456789ABCDE0},
- Expected: false,
- },
- } {
- t.Run(name, func(t *testing.T) {
- filter := SeccompFilter(0xf00, []SeccompSyscall{
- {
- Syscall: 1,
- Any: []SeccompConditions{{All: []SeccompCondition{tc.Condition}}},
- },
- })
- vm, err := bpf.NewVM(filter)
- require.NoError(t, err)
- result, err := vm.Run(seccompData(1, 0xf00, 0, tc.Args...))
- require.NoError(t, err)
- if tc.Expected {
- assert.Equal(t, SECCOMP_RET_ALLOW, result)
- } else {
- assert.Equal(t, int(SECCOMP_RET_ERRNO|syscall.EPERM), result)
- }
- })
- }
-}
diff --git a/plugin/rpcplugin/sandbox/supervisor.go b/plugin/rpcplugin/sandbox/supervisor.go
deleted file mode 100644
index 0e63954fd..000000000
--- a/plugin/rpcplugin/sandbox/supervisor.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "context"
- "fmt"
- "io"
- "path/filepath"
- "strings"
-
- "github.com/mattermost/mattermost-server/model"
- "github.com/mattermost/mattermost-server/plugin"
- "github.com/mattermost/mattermost-server/plugin/rpcplugin"
-)
-
-func SupervisorProvider(bundle *model.BundleInfo) (plugin.Supervisor, error) {
- return rpcplugin.SupervisorWithNewProcessFunc(bundle, func(ctx context.Context) (rpcplugin.Process, io.ReadWriteCloser, error) {
- executable := filepath.Clean(filepath.Join(".", bundle.Manifest.Backend.Executable))
- if strings.HasPrefix(executable, "..") {
- return nil, nil, fmt.Errorf("invalid backend executable")
- }
- return NewProcess(ctx, &Configuration{
- MountPoints: []*MountPoint{{
- Source: bundle.Path,
- Destination: "/plugin",
- ReadOnly: true,
- }},
- WorkingDirectory: "/plugin",
- }, filepath.Join("/plugin", executable))
- })
-}
diff --git a/plugin/rpcplugin/sandbox/supervisor_test.go b/plugin/rpcplugin/sandbox/supervisor_test.go
deleted file mode 100644
index 245185dd5..000000000
--- a/plugin/rpcplugin/sandbox/supervisor_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
-// See License.txt for license information.
-
-package sandbox
-
-import (
- "testing"
-
- "github.com/mattermost/mattermost-server/plugin/rpcplugin/rpcplugintest"
-)
-
-func TestSupervisorProvider(t *testing.T) {
- if err := CheckSupport(); err != nil {
- t.Skip("sandboxing not supported:", err)
- }
-
- rpcplugintest.TestSupervisorProvider(t, SupervisorProvider)
-}