Add seccomp filter to fsgofer

PiperOrigin-RevId: 211011542
Change-Id: Ib5a83a00f8eb6401603c6fb5b59afc93bac52558
This commit is contained in:
Fabricio Voznika
2018-08-30 17:30:19 -07:00
committed by Shentubot
parent 5ade9350ad
commit 3e493adf7a
8 changed files with 342 additions and 0 deletions
+1
View File
@@ -42,6 +42,7 @@ go_library(
"//runsc/console",
"//runsc/container",
"//runsc/fsgofer",
"//runsc/fsgofer/filter",
"//runsc/specutils",
"@com_github_google_subcommands//:go_default_library",
"@com_github_opencontainers_runtime-spec//specs-go:go_default_library",
+5
View File
@@ -28,6 +28,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/p9"
"gvisor.googlesource.com/gvisor/pkg/unet"
"gvisor.googlesource.com/gvisor/runsc/fsgofer"
"gvisor.googlesource.com/gvisor/runsc/fsgofer/filter"
"gvisor.googlesource.com/gvisor/runsc/specutils"
)
@@ -151,6 +152,10 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
Fatalf("too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs))
}
if err := filter.Install(); err != nil {
Fatalf("Failed to install seccomp filters: %v", err)
}
runServers(ats, g.ioFDs)
return subcommands.ExitSuccess
}
+24
View File
@@ -0,0 +1,24 @@
package(licenses = ["notice"]) # Apache 2.0
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "filter",
srcs = [
"config.go",
"extra_filters.go",
"extra_filters_msan.go",
"extra_filters_race.go",
"filter.go",
],
importpath = "gvisor.googlesource.com/gvisor/runsc/fsgofer/filter",
visibility = [
"//runsc:__subpackages__",
],
deps = [
"//pkg/abi/linux",
"//pkg/log",
"//pkg/seccomp",
"@org_golang_x_sys//unix:go_default_library",
],
)
+175
View File
@@ -0,0 +1,175 @@
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package filter
import (
"os"
"syscall"
"golang.org/x/sys/unix"
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
"gvisor.googlesource.com/gvisor/pkg/seccomp"
)
// allowedSyscalls is the set of syscalls executed by the gofer.
var allowedSyscalls = seccomp.SyscallRules{
syscall.SYS_ACCEPT: {},
syscall.SYS_ARCH_PRCTL: []seccomp.Rule{
{seccomp.AllowValue(linux.ARCH_GET_FS)},
{seccomp.AllowValue(linux.ARCH_SET_FS)},
},
syscall.SYS_CLOCK_GETTIME: {},
syscall.SYS_CLONE: []seccomp.Rule{
{
seccomp.AllowValue(
syscall.CLONE_VM |
syscall.CLONE_FS |
syscall.CLONE_FILES |
syscall.CLONE_SIGHAND |
syscall.CLONE_SYSVSEM |
syscall.CLONE_THREAD),
},
},
syscall.SYS_CLOSE: {},
syscall.SYS_DUP: {},
syscall.SYS_EPOLL_CTL: {},
syscall.SYS_EPOLL_PWAIT: []seccomp.Rule{
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(0),
},
},
syscall.SYS_EVENTFD2: []seccomp.Rule{
{
seccomp.AllowValue(0),
seccomp.AllowValue(0),
},
},
syscall.SYS_EXIT: {},
syscall.SYS_EXIT_GROUP: {},
syscall.SYS_FCHMOD: {},
syscall.SYS_FCHOWNAT: {},
syscall.SYS_FCNTL: []seccomp.Rule{
seccomp.Rule{
seccomp.AllowAny{},
seccomp.AllowValue(syscall.F_GETFL),
},
seccomp.Rule{
seccomp.AllowAny{},
seccomp.AllowValue(syscall.F_SETFL),
},
seccomp.Rule{
seccomp.AllowAny{},
seccomp.AllowValue(syscall.F_GETFD),
},
},
syscall.SYS_FSTAT: {},
syscall.SYS_FSTATFS: {},
syscall.SYS_FSYNC: {},
syscall.SYS_FTRUNCATE: {},
syscall.SYS_FUTEX: {
seccomp.Rule{
seccomp.AllowAny{},
seccomp.AllowValue(linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG),
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(0),
},
seccomp.Rule{
seccomp.AllowAny{},
seccomp.AllowValue(linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG),
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(0),
},
},
syscall.SYS_GETDENTS64: {},
syscall.SYS_GETPID: {},
unix.SYS_GETRANDOM: {},
syscall.SYS_GETTID: {},
syscall.SYS_GETTIMEOFDAY: {},
syscall.SYS_LINKAT: {},
syscall.SYS_LSEEK: {},
syscall.SYS_MKDIRAT: {},
syscall.SYS_MMAP: []seccomp.Rule{
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MAP_SHARED),
},
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MAP_PRIVATE | syscall.MAP_ANONYMOUS),
},
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MAP_PRIVATE | syscall.MAP_ANONYMOUS | syscall.MAP_FIXED),
},
},
syscall.SYS_MPROTECT: {},
syscall.SYS_MUNMAP: {},
syscall.SYS_NANOSLEEP: {},
syscall.SYS_NEWFSTATAT: {},
syscall.SYS_OPENAT: {},
syscall.SYS_POLL: {},
syscall.SYS_PREAD64: {},
syscall.SYS_PWRITE64: {},
syscall.SYS_READ: {},
syscall.SYS_READLINKAT: {},
syscall.SYS_RECVMSG: []seccomp.Rule{
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MSG_DONTWAIT | syscall.MSG_TRUNC),
},
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MSG_DONTWAIT | syscall.MSG_TRUNC | syscall.MSG_PEEK),
},
},
syscall.SYS_RENAMEAT: {},
syscall.SYS_RESTART_SYSCALL: {},
syscall.SYS_RT_SIGPROCMASK: {},
syscall.SYS_SCHED_YIELD: {},
syscall.SYS_SENDMSG: []seccomp.Rule{
{
seccomp.AllowAny{},
seccomp.AllowAny{},
seccomp.AllowValue(syscall.MSG_DONTWAIT | syscall.MSG_NOSIGNAL),
},
},
syscall.SYS_SHUTDOWN: []seccomp.Rule{
{seccomp.AllowAny{}, seccomp.AllowValue(syscall.SHUT_RDWR)},
},
syscall.SYS_SIGALTSTACK: {},
syscall.SYS_SYMLINKAT: {},
syscall.SYS_TGKILL: []seccomp.Rule{
{
seccomp.AllowValue(uint64(os.Getpid())),
},
},
syscall.SYS_UNLINKAT: {},
syscall.SYS_UTIMENSAT: {},
syscall.SYS_WRITE: {},
}
+28
View File
@@ -0,0 +1,28 @@
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !msan,!race
package filter
import (
"gvisor.googlesource.com/gvisor/pkg/seccomp"
)
// instrumentationFilters returns additional filters for syscalls used by
// Go intrumentation tools, e.g. -race, -msan.
// Returns empty when disabled.
func instrumentationFilters() seccomp.SyscallRules {
return nil
}
@@ -0,0 +1,33 @@
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build msan
package filter
import (
"syscall"
"gvisor.googlesource.com/gvisor/pkg/log"
"gvisor.googlesource.com/gvisor/pkg/seccomp"
)
// instrumentationFilters returns additional filters for syscalls used by MSAN.
func instrumentationFilters() seccomp.SyscallRules {
log.Warningf("*** SECCOMP WARNING: MSAN is enabled: syscall filters less restrictive!")
return seccomp.SyscallRules{
syscall.SYS_SCHED_GETAFFINITY: {},
syscall.SYS_SET_ROBUST_LIST: {},
}
}
@@ -0,0 +1,42 @@
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build race
package filter
import (
"syscall"
"gvisor.googlesource.com/gvisor/pkg/log"
"gvisor.googlesource.com/gvisor/pkg/seccomp"
)
// instrumentationFilters returns additional filters for syscalls used by TSAN.
func instrumentationFilters() seccomp.SyscallRules {
log.Warningf("*** SECCOMP WARNING: TSAN is enabled: syscall filters less restrictive!")
return seccomp.SyscallRules{
syscall.SYS_BRK: {},
syscall.SYS_CLONE: {},
syscall.SYS_FUTEX: {},
syscall.SYS_MADVISE: {},
syscall.SYS_MMAP: {},
syscall.SYS_MUNLOCK: {},
syscall.SYS_NANOSLEEP: {},
syscall.SYS_OPEN: {},
syscall.SYS_SET_ROBUST_LIST: {},
// Used within glibc's malloc.
syscall.SYS_TIME: {},
}
}
+34
View File
@@ -0,0 +1,34 @@
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package filter defines all syscalls the gofer is allowed to make, and
// installs seccomp filters to prevent prohibited syscalls in case it's
// compromised.
package filter
import (
"gvisor.googlesource.com/gvisor/pkg/seccomp"
)
// Install installs seccomp filters.
func Install() error {
s := allowedSyscalls
// Set of additional filters used by -race and -msan. Returns empty
// when not enabled.
s.Merge(instrumentationFilters())
// TODO: Set kill=true when SECCOMP_RET_KILL_PROCESS is supported.
return seccomp.Install(s, false)
}