diff --git a/cmd/oci-runtime-tool/main.go b/cmd/oci-runtime-tool/main.go index 7ced60de2..f3b4b0b72 100644 --- a/cmd/oci-runtime-tool/main.go +++ b/cmd/oci-runtime-tool/main.go @@ -27,6 +27,7 @@ func main() { app.Commands = []cli.Command{ generateCommand, bundleValidateCommand, + sanitizeCommand, } if err := app.Run(os.Args); err != nil { diff --git a/cmd/oci-runtime-tool/sanitize.go b/cmd/oci-runtime-tool/sanitize.go new file mode 100644 index 000000000..158a805ce --- /dev/null +++ b/cmd/oci-runtime-tool/sanitize.go @@ -0,0 +1,67 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "os" + + rspec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runtime-tools/sanitize" + "github.com/urfave/cli" +) + +var sanitizeFlags = []cli.Flag{ + cli.StringFlag{Name: "output", Usage: "output file (defaults to stdout)"}, +} + +var sanitizeCommand = cli.Command{ + Name: "sanitize", + Usage: "sanitize an OCI runtime configuration file", + Flags: sanitizeFlags, + Before: before, + Action: func(context *cli.Context) (err error) { + var reader io.ReadCloser + if context.NArg() == 0 { + reader = os.Stdin + } else if context.NArg() == 1 { + reader, err = os.Open(context.Args().First()) + if err != nil { + return err + } + defer reader.Close() + } else { + return fmt.Errorf("too many arguments (%d > 1)", context.NArg()) + } + + var config rspec.Spec + err = json.NewDecoder(reader).Decode(&config) + if err != nil { + return err + } + + err = reader.Close() + if err != nil { + return err + } + + err = sanitize.Sanitize(&config) + if err != nil { + return err + } + + var writer io.WriteCloser + if context.IsSet("output") { + writer, err = os.OpenFile(context.String("output"), os.O_WRONLY | os.O_TRUNC, 0) + if err != nil { + return err + } + defer writer.Close() + } else { + writer = os.Stdout + } + + encoder := json.NewEncoder(writer) + return encoder.Encode(&config) + }, +} diff --git a/sanitize/sanitize.go b/sanitize/sanitize.go new file mode 100644 index 000000000..4814fc026 --- /dev/null +++ b/sanitize/sanitize.go @@ -0,0 +1,76 @@ +// Package sanitize removes dangerous and questionably-portable properties from container configurations. +package sanitize + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// Santize removes dangerous and questionably-portable properties from container configurations. +func Sanitize(config *rspec.Spec) (err error) { + config.Process.Terminal = false + //config.Process.ConsoleSize = nil // needs runtime-spec#581 + config.Process.User.AdditionalGids = []uint32{} + config.Process.Capabilities = []string{} + config.Process.Rlimits = []rspec.Rlimit{} + config.Process.NoNewPrivileges = false + config.Process.ApparmorProfile = "" + config.Process.SelinuxLabel = "" + config.Root = rspec.Root{ + Path: "rootfs", + } + config.Hostname = "" + //config.Hooks = nil // needs runtime-spec#427 + + for i, _ := range config.Mounts { + config.Mounts[i].Source = "" + } + + if config.Linux != nil { + config.Linux.UIDMappings = []rspec.IDMapping{} + config.Linux.GIDMappings = []rspec.IDMapping{} + config.Linux.Sysctl = map[string]string{} + config.Linux.CgroupsPath = nil + config.Linux.Namespaces = []rspec.Namespace{} + config.Linux.Devices = []rspec.Device{} + config.Linux.Seccomp = nil + config.Linux.RootfsPropagation = "" + config.Linux.MaskedPaths = []string{} + config.Linux.MaskedPaths = []string{} + config.Linux.MountLabel = "" + + if config.Linux.Resources != nil { + config.Linux.Resources.Devices = []rspec.DeviceCgroup{} + config.Linux.Resources.DisableOOMKiller = nil + config.Linux.Resources.OOMScoreAdj= nil + config.Linux.Resources.Pids = nil + config.Linux.Resources.BlockIO = nil + config.Linux.Resources.HugepageLimits = []rspec.HugepageLimit{} + config.Linux.Resources.Network = nil + + if config.Linux.Resources.Memory != nil { + config.Linux.Resources.Memory.Kernel = nil + config.Linux.Resources.Memory.KernelTCP = nil + config.Linux.Resources.Memory.Swappiness = nil + } + + if config.Linux.Resources.CPU != nil { + config.Linux.Resources.CPU.Quota = nil + config.Linux.Resources.CPU.Period = nil + config.Linux.Resources.CPU.RealtimeRuntime = nil + config.Linux.Resources.CPU.Period = nil + config.Linux.Resources.CPU.Cpus = nil + config.Linux.Resources.CPU.Mems = nil + } + } + } + + if config.Solaris != nil { + config.Solaris.Milestone = "" + config.Solaris.LimitPriv = "" + config.Solaris.MaxShmMemory = "" + config.Solaris.Anet = []rspec.Anet{} + config.Solaris.CappedCPU = nil + } + + return nil +}