Skip to content

Commit b237189

Browse files
committed
daemon: add a flag to override the default seccomp profile
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
1 parent ecd806c commit b237189

File tree

15 files changed

+149
-22
lines changed

15 files changed

+149
-22
lines changed

api/server/router/system/system_routes.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,20 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
4242
if versions.LessThan(httputils.VersionFromContext(ctx), "1.25") {
4343
// TODO: handle this conversion in engine-api
4444
type oldInfo struct {
45-
*types.Info
45+
*types.InfoBase
4646
ExecutionDriver string
47+
SecurityOptions []string
4748
}
48-
return httputils.WriteJSON(w, http.StatusOK, &oldInfo{Info: info, ExecutionDriver: "<not supported>"})
49+
old := &oldInfo{
50+
InfoBase: info.InfoBase,
51+
ExecutionDriver: "<not supported>",
52+
}
53+
for _, s := range info.SecurityOptions {
54+
if s.Key == "Name" {
55+
old.SecurityOptions = append(old.SecurityOptions, s.Value)
56+
}
57+
}
58+
return httputils.WriteJSON(w, http.StatusOK, old)
4959
}
5060
return httputils.WriteJSON(w, http.StatusOK, info)
5161
}

api/types/types.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ type Version struct {
142142
BuildTime string `json:",omitempty"`
143143
}
144144

145-
// Info contains response of Remote API:
145+
// InfoBase contains the base response of Remote API:
146146
// GET "/info"
147-
type Info struct {
147+
type InfoBase struct {
148148
ID string
149149
Containers int
150150
ContainersRunning int
@@ -191,7 +191,6 @@ type Info struct {
191191
ServerVersion string
192192
ClusterStore string
193193
ClusterAdvertise string
194-
SecurityOptions []string
195194
Runtimes map[string]Runtime
196195
DefaultRuntime string
197196
Swarm swarm.Info
@@ -202,6 +201,18 @@ type Info struct {
202201
Isolation container.Isolation
203202
}
204203

204+
// SecurityOpt holds key/value pair about a security option
205+
type SecurityOpt struct {
206+
Key, Value string
207+
}
208+
209+
// Info contains response of Remote API:
210+
// GET "/info"
211+
type Info struct {
212+
*InfoBase
213+
SecurityOptions []SecurityOpt
214+
}
215+
205216
// PluginsInfo is a temp struct holding Plugins name
206217
// registered with docker daemon. It is used by Info struct
207218
type PluginsInfo struct {

cli/command/system/info.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,20 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
140140
}
141141

142142
if info.OSType == "linux" {
143-
fmt.Fprintf(dockerCli.Out(), "Security Options:")
144-
ioutils.FprintfIfNotEmpty(dockerCli.Out(), " %s", strings.Join(info.SecurityOptions, " "))
145-
fmt.Fprintf(dockerCli.Out(), "\n")
143+
if len(info.SecurityOptions) != 0 {
144+
fmt.Fprintf(dockerCli.Out(), "Security Options:\n")
145+
for _, o := range info.SecurityOptions {
146+
switch o.Key {
147+
case "Name":
148+
fmt.Fprintf(dockerCli.Out(), " %s\n", o.Value)
149+
case "Profile":
150+
if o.Key != "default" {
151+
fmt.Fprintf(dockerCli.Err(), " WARNING: You're not using the Docker's default seccomp profile\n")
152+
}
153+
fmt.Fprintf(dockerCli.Out(), " %s: %s\n", o.Key, o.Value)
154+
}
155+
}
156+
}
146157
}
147158

148159
// Isolation only has meaning on a Windows daemon.

client/info_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ func TestInfo(t *testing.T) {
4646
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
4747
}
4848
info := &types.Info{
49-
ID: "daemonID",
50-
Containers: 3,
49+
InfoBase: &types.InfoBase{
50+
ID: "daemonID",
51+
Containers: 3,
52+
},
5153
}
5254
b, err := json.Marshal(info)
5355
if err != nil {

daemon/config_unix.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type Config struct {
3939
OOMScoreAdjust int `json:"oom-score-adjust,omitempty"`
4040
Init bool `json:"init,omitempty"`
4141
InitPath string `json:"init-path,omitempty"`
42+
SeccompProfile string `json:"seccomp-profile,omitempty"`
4243
}
4344

4445
// bridgeConfig stores all the bridge driver specific
@@ -101,6 +102,7 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
101102
flags.StringVar(&config.InitPath, "init-path", "", "Path to the docker-init binary")
102103
flags.Int64Var(&config.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
103104
flags.Int64Var(&config.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
105+
flags.StringVar(&config.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
104106

105107
config.attachExperimentalFlags(flags)
106108
}

daemon/daemon.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ type Daemon struct {
104104
defaultIsolation containertypes.Isolation // Default isolation mode on Windows
105105
clusterProvider cluster.Provider
106106
cluster Cluster
107+
108+
seccompProfile []byte
109+
seccompProfilePath string
107110
}
108111

109112
// HasExperimental returns whether the experimental features of the daemon are enabled or not
@@ -530,6 +533,10 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
530533
}
531534
}()
532535

536+
if err := d.setupSeccompProfile(); err != nil {
537+
return nil, err
538+
}
539+
533540
// Set the default isolation mode (only applicable on Windows)
534541
if err := d.setDefaultIsolation(); err != nil {
535542
return nil, fmt.Errorf("error setting default isolation mode: %v", err)

daemon/daemon_solaris.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,7 @@ func setupDaemonProcess(config *Config) error {
177177
func (daemon *Daemon) verifyVolumesInfo(container *container.Container) error {
178178
return nil
179179
}
180+
181+
func (daemon *Daemon) setupSeccompProfile() error {
182+
return nil
183+
}

daemon/daemon_unix.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package daemon
44

55
import (
66
"bytes"
7+
"encoding/json"
78
"fmt"
89
"io/ioutil"
910
"net"
@@ -1242,6 +1243,23 @@ func (daemon *Daemon) initCgroupsPath(path string) error {
12421243
return err
12431244
}
12441245
}
1246+
return nil
1247+
}
12451248

1249+
func (daemon *Daemon) setupSeccompProfile() error {
1250+
if daemon.configStore.SeccompProfile != "" {
1251+
daemon.seccompProfilePath = daemon.configStore.SeccompProfile
1252+
b, err := ioutil.ReadFile(daemon.configStore.SeccompProfile)
1253+
if err != nil {
1254+
return fmt.Errorf("opening seccomp profile (%s) failed: %v", daemon.configStore.SeccompProfile, err)
1255+
}
1256+
daemon.seccompProfile = b
1257+
p := struct {
1258+
DefaultAction string `json:"defaultAction"`
1259+
}{}
1260+
if err := json.Unmarshal(daemon.seccompProfile, &p); err != nil {
1261+
return err
1262+
}
1263+
}
12461264
return nil
12471265
}

daemon/daemon_windows.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,3 +532,7 @@ func setupDaemonProcess(config *Config) error {
532532
func (daemon *Daemon) verifyVolumesInfo(container *container.Container) error {
533533
return nil
534534
}
535+
536+
func (daemon *Daemon) setupSeccompProfile() error {
537+
return nil
538+
}

daemon/info.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,29 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
6868
}
6969
})
7070

71-
var securityOptions []string
71+
securityOptions := []types.SecurityOpt{}
7272
if sysInfo.AppArmor {
73-
securityOptions = append(securityOptions, "apparmor")
73+
securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "apparmor"})
7474
}
7575
if sysInfo.Seccomp && supportsSeccomp {
76-
securityOptions = append(securityOptions, "seccomp")
76+
profile := daemon.seccompProfilePath
77+
if profile == "" {
78+
profile = "default"
79+
}
80+
securityOptions = append(securityOptions,
81+
types.SecurityOpt{Key: "Name", Value: "seccomp"},
82+
types.SecurityOpt{Key: "Profile", Value: profile},
83+
)
7784
}
7885
if selinuxEnabled() {
79-
securityOptions = append(securityOptions, "selinux")
86+
securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "selinux"})
8087
}
8188
uid, gid := daemon.GetRemappedUIDGID()
8289
if uid != 0 || gid != 0 {
83-
securityOptions = append(securityOptions, "userns")
90+
securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "userns"})
8491
}
8592

86-
v := &types.Info{
93+
v := &types.InfoBase{
8794
ID: daemon.ID,
8895
Containers: int(cRunning + cPaused + cStopped),
8996
ContainersRunning: int(cRunning),
@@ -120,7 +127,6 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
120127
HTTPProxy: sockets.GetProxyEnv("http_proxy"),
121128
HTTPSProxy: sockets.GetProxyEnv("https_proxy"),
122129
NoProxy: sockets.GetProxyEnv("no_proxy"),
123-
SecurityOptions: securityOptions,
124130
LiveRestoreEnabled: daemon.configStore.LiveRestoreEnabled,
125131
Isolation: daemon.defaultIsolation,
126132
}
@@ -150,7 +156,12 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
150156
}
151157
v.Name = hostname
152158

153-
return v, nil
159+
i := &types.Info{
160+
InfoBase: v,
161+
SecurityOptions: securityOptions,
162+
}
163+
164+
return i, nil
154165
}
155166

156167
// SystemVersion returns version information about the daemon.

0 commit comments

Comments
 (0)