Skip to content

Commit

Permalink
Merge pull request #6 from AkihiroSuda/drop-libseccomp
Browse files Browse the repository at this point in the history
Remove dependency on libseccomp
  • Loading branch information
AkihiroSuda authored Jan 10, 2025
2 parents 1980dcc + 17f8e4b commit 3a97f73
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 39 deletions.
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

0 comments on commit 3a97f73

Please sign in to comment.