Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency on libseccomp #6

Merged
merged 2 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ jobs:
- name: Install
run: |
set -eux
sudo apt-get update
sudo apt-get install -y libseccomp-dev
make
sudo make install
- name: Smoke test
Expand Down
14 changes: 2 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
FROM tonistiigi/xx:1.6.1@sha256:923441d7c25f1e2eb5789f82d987693c47b8ed987c4ab3b075d6ed2b5d6779a3 AS xx

FROM --platform=$BUILDPLATFORM golang:1.23.4-bookworm@sha256:2e838582004fab0931693a3a84743ceccfbfeeafa8187e87291a1afea457ff7a AS build
COPY --from=xx / /
ENV DEBIAN_FRONTEND=noninteractive
ARG TARGETARCH
RUN xx-apt-get update -qq && xx-apt-get install -qq --no-install-recommends \
binutils \
gcc \
libc6-dev \
libseccomp-dev \
pkg-config
RUN --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go \
--mount=type=bind,src=.,target=/src,rw=true \
cd /src && \
GO=xx-go STATIC=1 make && \
xx-verify --static _output/bin/gomodjail && \
GOARCH=$TARGETARCH STATIC=1 make && \
readelf -d _output/bin/gomodjail | grep -q "no dynamic" && \
cp -a _output /

FROM scratch
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GO_BUILD ?= $(GO) build -trimpath -ldflags="$(GO_LDFLAGS)"
STATIC ?=
ifeq ($(STATIC),1)
GO_LDFLAGS += -extldflags -static
export CGO_ENABLED=1
export CGO_ENABLED=0
endif

DOCKER ?= docker
Expand Down Expand Up @@ -45,7 +45,8 @@ clean:
rm -rf _output _artifacts

define make_artifact
$(DOCKER_BUILD) --platform $(1)/$(2) --output type=tar,dest=_artifacts/gomodjail-$(VERSION).$(1)-$(2).tar.gz .
$(DOCKER_BUILD) --platform $(1)/$(2) --output type=tar,dest=_artifacts/gomodjail-$(VERSION).$(1)-$(2).tar .
gzip -9n _artifacts/gomodjail-$(VERSION).$(1)-$(2).tar
endef

.PHONY: artifacts
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ Runtime dependencies:

Build dependencies:
- [Go](https://go.dev/dl/)
- gcc
- libseccomp-dev (apt), libseccomp-devel (dnf)

## Install
```bash
sudo apt install -y build-essential libseccomp-dev
make
sudo make install
```
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/AkihiroSuda/gomodjail
go 1.23

require (
github.com/seccomp/libseccomp-golang v0.10.0
github.com/elastic/go-seccomp-bpf v1.5.0
github.com/spf13/cobra v1.8.1
golang.org/x/mod v0.22.0
golang.org/x/sys v0.29.0
Expand All @@ -12,4 +12,5 @@ require (
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.24.0 // indirect
)
13 changes: 11 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elastic/go-seccomp-bpf v1.5.0 h1:gJV+U1iP+YC70ySyGUUNk2YLJW5/IkEw4FZBJfW8ZZY=
github.com/elastic/go-seccomp-bpf v1.5.0/go.mod h1:umdhQ/3aybliBF2jjiZwS492I/TOKz+ZRvsLT3hVe1o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
49 changes: 35 additions & 14 deletions pkg/child/child_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,27 @@ import (

"github.com/AkihiroSuda/gomodjail/pkg/env"
"github.com/AkihiroSuda/gomodjail/pkg/profile/seccompprofile"
seccomp "github.com/seccomp/libseccomp-golang"
seccomp "github.com/elastic/go-seccomp-bpf"
"github.com/elastic/go-seccomp-bpf/arch"
)

func withoutUnknownSyscalls(ss []string) []string {
archInfo, err := arch.GetInfo("")
if err != nil {
panic(err)
}
var res []string
for _, s := range ss {
if _, ok := archInfo.SyscallNames[s]; ok {
res = append(res, s)
} else {
slog.Debug("Ignoring syscall not supported on this arch",
"syscallName", s, "arch", archInfo.ID.String())
}
}
return res
}

func Main(args []string) error {
if os.Geteuid() == 0 {
// seccompprofile is not ready to cover privileged syscalls yet.
Expand All @@ -21,23 +39,26 @@ func Main(args []string) error {
if err != nil {
return err
}
filter, err := seccomp.NewFilter(seccomp.ActTrace)
if err != nil {
return fmt.Errorf("failed to create a seccomp filter: %w", err)
os.Unsetenv(env.PrivateChild)

seccompPolicy := seccomp.Policy{
DefaultAction: seccomp.ActionTrace,
Syscalls: []seccomp.SyscallGroup{
{
Names: withoutUnknownSyscalls(seccompprofile.AlwaysAllowed),
Action: seccomp.ActionAllow,
},
},
}
for _, syscallName := range seccompprofile.AlwaysAllowed {
sc, err := seccomp.GetSyscallFromName(syscallName)
if err != nil {
return fmt.Errorf("failed to get syscall %q: %w", syscallName, err)
}
if err := filter.AddRule(sc, seccomp.ActAllow); err != nil {
return fmt.Errorf("failed to add a rule for %q: %w", syscallName, err)
}
seccompFilter := seccomp.Filter{
NoNewPrivs: true,
Flag: seccomp.FilterFlagTSync,
Policy: seccompPolicy,
}
if err := filter.Load(); err != nil {
if err := seccomp.LoadFilter(seccompFilter); err != nil {
return fmt.Errorf("failed to load the seccomp filter: %w", err)
}
os.Unsetenv(env.PrivateChild)

if err := syscall.Exec(arg0, args, os.Environ()); err != nil {
return fmt.Errorf("failed to execute %q %v: %w", arg0, args, err)
}
Expand Down
15 changes: 12 additions & 3 deletions pkg/tracer/tracer_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/AkihiroSuda/gomodjail/pkg/profile"
"github.com/AkihiroSuda/gomodjail/pkg/tracer/regs"
"github.com/AkihiroSuda/gomodjail/pkg/unwinder"
seccomp "github.com/seccomp/libseccomp-golang"
"github.com/elastic/go-seccomp-bpf/arch"
"golang.org/x/sys/unix"
)

Expand All @@ -24,12 +24,17 @@ func New(cmd *exec.Cmd, profile *profile.Profile) (*Tracer, error) {
return nil, err
}
cmd.SysProcAttr = &unix.SysProcAttr{Ptrace: true}
archInfo, err := arch.GetInfo("")
if err != nil {
return nil, err
}
tracer := &Tracer{
cmd: cmd,
profile: profile,
selfExe: selfExe,
pids: make(map[int]string),
unwinders: make(map[string]*unwinder.Unwinder),
archInfo: archInfo,
}
for k, v := range profile.Modules {
slog.Debug("Loading profile", "module", k, "policy", v)
Expand All @@ -43,6 +48,7 @@ type Tracer struct {
selfExe string
pids map[int]string // key: pid, value: file name
unwinders map[string]*unwinder.Unwinder // key: file name
archInfo *arch.Info
}

const commonPtraceOptions = unix.PTRACE_O_TRACEFORK |
Expand Down Expand Up @@ -130,8 +136,9 @@ func (tracer *Tracer) Trace() error {

func (tracer *Tracer) handleSyscall(pid int, regs *regs.Regs) error {
syscallNr := regs.Syscall()
syscallName, err := seccomp.ScmpSyscall(syscallNr).GetName()
if err != nil {
// FIXME: check the seccomp arch
syscallName, ok := tracer.archInfo.SyscallNumbers[int(syscallNr)]
if !ok {
return fmt.Errorf("unknown syscall %d", syscallNr)
}
switch syscallName {
Expand All @@ -143,6 +150,7 @@ func (tracer *Tracer) handleSyscall(pid int, regs *regs.Regs) error {
}
filename, ok := tracer.pids[pid]
if !ok {
var err error
filename, err = os.Readlink(fmt.Sprintf("/proc/%d/exe", pid))
if err != nil {
return err
Expand All @@ -154,6 +162,7 @@ func (tracer *Tracer) handleSyscall(pid int, regs *regs.Regs) error {
}
uw, ok := tracer.unwinders[filename]
if !ok {
var err error
uw, err = unwinder.New(filename)
if err != nil { // No gosymtab
tracer.unwinders[filename] = nil
Expand Down