mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add command-line tool to quickly dump the Sentry BPF program.
PiperOrigin-RevId: 573994110
This commit is contained in:
committed by
gVisor bot
parent
15fdd74e5c
commit
e69b01c3a8
@@ -0,0 +1,30 @@
|
||||
load("//tools:defs.bzl", "go_binary", "go_test")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
licenses = ["notice"],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "dumpfilter",
|
||||
srcs = [
|
||||
"dumpfilter.go",
|
||||
"dumpfilter_unsafe.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/bpf",
|
||||
"//pkg/log",
|
||||
"//pkg/seccomp",
|
||||
"//pkg/sentry/platform/systrap",
|
||||
"//runsc/boot/filter",
|
||||
"//runsc/flag",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "dumpfilter_test",
|
||||
srcs = ["dumpfilter_test.go"],
|
||||
data = [":dumpfilter"],
|
||||
deps = ["//pkg/test/testutil"],
|
||||
)
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// dumpfilter dumps the seccomp-bpf program used by the Sentry.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/bpf"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/seccomp"
|
||||
"gvisor.dev/gvisor/pkg/sentry/platform/systrap"
|
||||
"gvisor.dev/gvisor/runsc/boot/filter"
|
||||
"gvisor.dev/gvisor/runsc/flag"
|
||||
)
|
||||
|
||||
// Flags.
|
||||
var (
|
||||
output = flag.String("output", "fancy", "Output type: 'fancy' (human-readable with line numbers resolved), 'plain' (diffable but still human-readable output), 'bytecode' (dump raw bytecode)")
|
||||
nvproxy = flag.Bool("nvproxy", false, "Enable nvproxy in filter configuration")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
rules, denyRules := filter.Rules(filter.Options{
|
||||
Platform: &systrap.Systrap{},
|
||||
NVProxy: *nvproxy,
|
||||
})
|
||||
insns, stats, err := seccomp.BuildProgram([]seccomp.RuleSet{
|
||||
{
|
||||
Rules: denyRules,
|
||||
Action: linux.SECCOMP_RET_ERRNO,
|
||||
},
|
||||
{
|
||||
Rules: rules,
|
||||
Action: linux.SECCOMP_RET_ALLOW,
|
||||
},
|
||||
}, linux.SECCOMP_RET_ERRNO, linux.SECCOMP_RET_ERRNO)
|
||||
if err != nil {
|
||||
log.Warningf("%v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
log.Infof("Size before optimizations: %d", stats.SizeBeforeOptimizations)
|
||||
log.Infof("Size after optimizations: %d", stats.SizeAfterOptimizations)
|
||||
log.Infof("Build duration: %v", stats.BuildDuration)
|
||||
log.Infof("Optimization passes duration: %v", stats.OptimizeDuration)
|
||||
log.Infof("Total duration: %v", stats.BuildDuration+stats.OptimizeDuration)
|
||||
switch *output {
|
||||
case "fancy":
|
||||
dump, err := bpf.DecodeInstructions(insns)
|
||||
if err != nil {
|
||||
log.Warningf("%v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Print(dump)
|
||||
case "plain":
|
||||
for _, ins := range insns {
|
||||
fmt.Println(ins.String())
|
||||
}
|
||||
case "bytecode":
|
||||
if _, err := os.Stdout.WriteString(InstructionsToBytecode(insns)); err != nil {
|
||||
log.Warningf("cannot write bytecode to stdout: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// 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 dumpfilter_test
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/test/testutil"
|
||||
)
|
||||
|
||||
// TestDumpFilter tests that the `dumpfilter` program works.
|
||||
func TestDumpFilter(t *testing.T) {
|
||||
binPath, err := testutil.FindFile("runsc/boot/filter/dumpfilter/dumpfilter")
|
||||
if err != nil {
|
||||
t.Fatalf("cannot locate dumpfilter: %v", err)
|
||||
}
|
||||
output, err := exec.Command(binPath).CombinedOutput()
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
t.Log(line)
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("program failed: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2023 The gVisor Authors.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// dumpfilter dumps the seccomp-bpf program used by the Sentry.
|
||||
package main
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/bpf"
|
||||
)
|
||||
|
||||
// InstructionsToBytecode returns raw the BPF bytecode for the given program.
|
||||
func InstructionsToBytecode(insns []bpf.Instruction) string {
|
||||
bytePointer := (*byte)(unsafe.Pointer(&insns[0]))
|
||||
return unsafe.String(bytePointer, len(insns)*int(unsafe.Sizeof(bpf.Instruction{})))
|
||||
}
|
||||
Reference in New Issue
Block a user