Skip to content

Commit

Permalink
Merge pull request #20 from kinvolk/alban_freeze2
Browse files Browse the repository at this point in the history
Implement freeze handler
  • Loading branch information
alban authored Feb 16, 2022
2 parents d847582 + d0d02ac commit bc435a1
Show file tree
Hide file tree
Showing 446 changed files with 52,786 additions and 8,764 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# We need alpine edge for libseccomp-2.5.0

FROM golang:1.15-alpine as builder
FROM golang:1.17-alpine as builder
RUN apk add alpine-sdk

RUN \
Expand Down
2 changes: 2 additions & 0 deletions cmd/seccompagent/seccompagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func main() {
// container instead of just the process making the syscall.
case "kill-container":
r.DefaultHandler = handlers.KillContainer(podCtx.Pid1)
case "freeze-container":
r.DefaultHandler = handlers.FreezeContainer(podCtx.Pid1)
default:
log.WithFields(log.Fields{
"pod": podCtx,
Expand Down
10 changes: 10 additions & 0 deletions deploy/seccompagent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ spec:
fieldRef:
fieldPath: spec.nodeName
securityContext:
# We need to keep 'privileged' to opt out of cgroupns, so we can
# inspect containers' cgroups via their /proc/$pid/cgroup files.
privileged: true
capabilities:
add:
# CAP_SYS_PTRACE is useful to read arguments of a processes with
Expand All @@ -65,6 +68,10 @@ spec:
mountPath: /host/seccomp
- name: run
mountPath: /run
# the freezer handler needs write access to the cgroup filesystems to
# write "FROZEN" on "freezer.state" interface file.
- name: cgroup
mountPath: /sys/fs/cgroup
tolerations:
- effect: NoSchedule
operator: Exists
Expand All @@ -77,3 +84,6 @@ spec:
- name: run
hostPath:
path: /run
- name: cgroup
hostPath:
path: /sys/fs/cgroup
2 changes: 1 addition & 1 deletion docs/profiles/notify-dangerous.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"SCMP_ARCH_X86_64"
],
"listenerPath": "/run/seccomp-agent.socket",
"listenerMetadata": "DEFAULT_ACTION=kill-container",
"listenerMetadata": "DEFAULT_ACTION=freeze-container",
"syscalls": [
{
"action": "SCMP_ACT_NOTIFY",
Expand Down
3 changes: 2 additions & 1 deletion docs/profiles/notify-dangerous.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ spec:
architectures:
- SCMP_ARCH_X86_64
listenerPath: "/run/seccomp-agent.socket"
listenerMetadata: "DEFAULT_ACTION=kill-container"
#listenerMetadata: "DEFAULT_ACTION=kill-container"
listenerMetadata: "DEFAULT_ACTION=freeze-container"

syscalls:

Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ go 1.15

require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.5.4 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210319114652-9c848d91e8cf
github.com/opencontainers/runc v1.1.0
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921
github.com/sirupsen/logrus v1.7.0
github.com/sirupsen/logrus v1.8.1
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c
k8s.io/api v0.20.4
k8s.io/apimachinery v0.20.4
k8s.io/client-go v0.20.4
Expand Down
58 changes: 49 additions & 9 deletions go.sum

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions pkg/handlers/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
package handlers

import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"

libctManager "github.com/opencontainers/runc/libcontainer/cgroups/manager"
libctConfig "github.com/opencontainers/runc/libcontainer/configs"
libseccomp "github.com/seccomp/libseccomp-golang"
log "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
Expand Down Expand Up @@ -49,3 +55,90 @@ func KillContainer(pid int) registry.HandlerFunc {
return registry.HandlerResultErrno(unix.EPERM)
}
}

// freezerCgroupPath parses /proc/$pid/cgroup and find the cgroup path from
// - either the freezer cgroup (starting with '%d:freezer:'), or
// - the unified hierarchy (starting with '0::')
func freezerCgroupPath(pid int) string {
var err error
var cgroupFile *os.File
if cgroupFile, err = os.Open(filepath.Join("/proc", fmt.Sprintf("%d", pid), "cgroup")); err != nil {
log.WithFields(log.Fields{
"pid": pid,
"err": err,
}).Error("cannot parse cgroup")
return ""
}
defer cgroupFile.Close()

reader := bufio.NewReader(cgroupFile)
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
line = strings.TrimSuffix(line, "\n")
fields := strings.SplitN(line, ":", 3)
if len(fields) != 3 {
continue
}
cgroupHierarchyID := fields[0]
cgroupControllerList := fields[1]
cgroupPath := fields[2]

for _, cgroupController := range strings.Split(cgroupControllerList, ",") {
if cgroupController == "freezer" {
return cgroupPath
}
}
if cgroupHierarchyID == "0" && cgroupControllerList == "" {
return cgroupPath
}
}
return ""
}

func FreezeContainer(pid int) registry.HandlerFunc {
cgroupPath := freezerCgroupPath(pid)
return func(fd libseccomp.ScmpFd, req *libseccomp.ScmpNotifReq) (result registry.HandlerResult) {
if cgroupPath == "" {
log.WithFields(log.Fields{
"pid": pid,
}).Error("cgroup path not found")
return registry.HandlerResultErrno(unix.EPERM)
}

if cgroupPath == "/" {
log.WithFields(log.Fields{
"pid": pid,
}).Error("refuse to use root cgroup")
return registry.HandlerResultErrno(unix.EPERM)
}

cgroup := &libctConfig.Cgroup{
Path: cgroupPath,
Resources: &libctConfig.Resources{},
}

m, err := libctManager.New(cgroup)
if err != nil {
log.WithFields(log.Fields{
"pid": pid,
"cgroupPath": cgroupPath,
"err": err,
}).Error("cannot create new cgroup manager")
return registry.HandlerResultErrno(unix.EPERM)
}

if err := m.Freeze(libctConfig.Frozen); err != nil {
log.WithFields(log.Fields{
"pid": pid,
"cgroupPath": cgroupPath,
"err": err,
}).Error("cannot freeze cgroup")
return registry.HandlerResultErrno(unix.EPERM)
}

return registry.HandlerResultErrno(unix.EPERM)
}
}
4 changes: 2 additions & 2 deletions pkg/kuberesolver/kuberesolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func KubeResolver(f KubeResolverFunc) (registry.ResolverFunc, error) {
"container": podCtx.Container,
"err": err,
}).Trace("Pod details found from annotations")
return f(nil, vars)
return f(podCtx, vars)
}

pod, err := k8sClient.ContainerLookup(state.State.Pid)
Expand All @@ -129,7 +129,7 @@ func KubeResolver(f KubeResolverFunc) (registry.ResolverFunc, error) {
"pid": state.State.Pid,
"err": err,
}).Error("Cannot find container in Kubernetes")
return f(nil, vars)
return f(podCtx, vars)
}
podCtx.Namespace = pod.ObjectMeta.Namespace
podCtx.Pod = pod.ObjectMeta.Name
Expand Down
17 changes: 17 additions & 0 deletions vendor/github.com/cilium/ebpf/.clang-format

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions vendor/github.com/cilium/ebpf/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions vendor/github.com/cilium/ebpf/.golangci.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 80 additions & 0 deletions vendor/github.com/cilium/ebpf/ARCHITECTURE.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions vendor/github.com/cilium/ebpf/CODE_OF_CONDUCT.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit bc435a1

Please sign in to comment.