diff --git a/seccomp-wrapper/seccomp-wrapper b/seccomp-wrapper/seccomp-wrapper new file mode 100755 index 0000000..12bde78 Binary files /dev/null and b/seccomp-wrapper/seccomp-wrapper differ diff --git a/seccomp-wrapper/seccomp-wrapper.go b/seccomp-wrapper/seccomp-wrapper.go new file mode 100644 index 0000000..a9b941b --- /dev/null +++ b/seccomp-wrapper/seccomp-wrapper.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "os" + "syscall" + + "github.com/op/go-logging" + "github.com/subgraph/go-seccomp" + "github.com/subgraph/oz" +) + +func createLogger() *logging.Logger { + l := logging.MustGetLogger("seccomp-wrapper") + be := logging.NewLogBackend(os.Stderr, "", 0) + f := logging.MustStringFormatter("%{level:.1s} %{message}") + fbe := logging.NewBackendFormatter(be, f) + logging.SetBackend(fbe) + return l +} + +func main() { + log := createLogger() + + if len(os.Args) < 3 { + log.Error("seccomp-wrapper: Not enough arguments.") + os.Exit(1) + } + + var getvar = func(name string) string { + val := os.Getenv(name) + if val == "" { + log.Error("Error: missing required '%s' argument", name) + os.Exit(1) + } + return val + } + + cmd := os.Args[2] + cmdArgs := os.Args[2:] + env := os.Environ() + pname := getvar("INIT_PROFILE") + + config, err := oz.LoadConfig(oz.DefaultConfigPath) + if err != nil { + if os.IsNotExist(err) { + log.Info("Configuration file (%s) is missing, using defaults.", oz.DefaultConfigPath) + config = oz.NewDefaultConfig() + } else { + log.Error("Could not load configuration: %s", oz.DefaultConfigPath, err) + os.Exit(1) + } + } + + p, err := loadProfile(config.ProfileDir, pname) + + if err != nil { + log.Error("Could not load profile %s: %v", pname, err) + os.Exit(1) + } + + switch os.Args[1] { + case "-w": + if p.Seccomp.Seccomp_Whitelist == "" { + log.Error("No seccomp policy file.") + os.Exit(1) + } + filter, err := seccomp.Compile(p.Seccomp.Seccomp_Whitelist) + if err != nil { + log.Error("Seccomp filter compile failed: %v", err) + os.Exit(1) + } + err = seccomp.Install(filter) + if err != nil { + log.Error("Error (seccomp): %v", err) + os.Exit(1) + } + err = syscall.Exec(cmd, cmdArgs, env) + if err != nil { + log.Error("Error (exec): %v", err) + os.Exit(1) + } + case "-b": + fmt.Println("Not yet implemented.") + os.Exit(1) + default: + fmt.Println("Bad switch.") + os.Exit(1) + } +} + +func loadProfile(dir, name string) (*oz.Profile, error) { + ps, err := oz.LoadProfiles(dir) + if err != nil { + return nil, err + } + for _, p := range ps { + if name == p.Name { + return p, nil + } + } + return nil, fmt.Errorf("no profile named '%s'", name) +}