Browse code

Move security opts to HostConfig

These settings need to be in the HostConfig so that they are not
committed to an image and cannot introduce a security issue.

We can safely move this field from the Config to the HostConfig
without any regressions because these settings are consumed at container
created and used to populate fields on the Container struct. Because of
this, existing settings will be honored for containers already created
on a daemon with custom security settings and prevent values being
consumed via an Image.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Conflicts:
daemon/create.go
changing config to hostConfig was required to fix the
build

Michael Crosby authored on 2014/11/04 07:57:18
Showing 7 changed files
... ...
@@ -83,8 +83,8 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
83 83
 	if warnings, err = daemon.mergeAndVerifyConfig(config, img); err != nil {
84 84
 		return nil, nil, err
85 85
 	}
86
-	if hostConfig != nil && config.SecurityOpt == nil {
87
-		config.SecurityOpt, err = daemon.GenerateSecurityOpt(hostConfig.IpcMode)
86
+	if hostConfig != nil && hostConfig.SecurityOpt == nil {
87
+		hostConfig.SecurityOpt, err = daemon.GenerateSecurityOpt(hostConfig.IpcMode)
88 88
 		if err != nil {
89 89
 			return nil, nil, err
90 90
 		}
... ...
@@ -531,10 +531,10 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint, configCmd []string)
531 531
 	return entrypoint, args
532 532
 }
533 533
 
534
-func parseSecurityOpt(container *Container, config *runconfig.Config) error {
534
+func parseSecurityOpt(container *Container, config *runconfig.HostConfig) error {
535 535
 	var (
536
-		label_opts []string
537
-		err        error
536
+		labelOpts []string
537
+		err       error
538 538
 	)
539 539
 
540 540
 	for _, opt := range config.SecurityOpt {
... ...
@@ -544,7 +544,7 @@ func parseSecurityOpt(container *Container, config *runconfig.Config) error {
544 544
 		}
545 545
 		switch con[0] {
546 546
 		case "label":
547
-			label_opts = append(label_opts, con[1])
547
+			labelOpts = append(labelOpts, con[1])
548 548
 		case "apparmor":
549 549
 			container.AppArmorProfile = con[1]
550 550
 		default:
... ...
@@ -552,7 +552,7 @@ func parseSecurityOpt(container *Container, config *runconfig.Config) error {
552 552
 		}
553 553
 	}
554 554
 
555
-	container.ProcessLabel, container.MountLabel, err = label.InitLabels(label_opts)
555
+	container.ProcessLabel, container.MountLabel, err = label.InitLabels(labelOpts)
556 556
 	return err
557 557
 }
558 558
 
... ...
@@ -586,7 +586,6 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, img *i
586 586
 		execCommands:    newExecStore(),
587 587
 	}
588 588
 	container.root = daemon.containerRoot(container.ID)
589
-	err = parseSecurityOpt(container, config)
590 589
 	return container, err
591 590
 }
592 591
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 
9 9
 func TestParseSecurityOpt(t *testing.T) {
10 10
 	container := &Container{}
11
-	config := &runconfig.Config{}
11
+	config := &runconfig.HostConfig{}
12 12
 
13 13
 	// test apparmor
14 14
 	config.SecurityOpt = []string{"apparmor:test_profile"}
... ...
@@ -44,6 +44,9 @@ func (daemon *Daemon) ContainerStart(job *engine.Job) engine.Status {
44 44
 }
45 45
 
46 46
 func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.HostConfig) error {
47
+	if err := parseSecurityOpt(container, hostConfig); err != nil {
48
+		return err
49
+	}
47 50
 	// Validate the HostConfig binds. Make sure that:
48 51
 	// the source exists
49 52
 	for _, bind := range hostConfig.Binds {
... ...
@@ -33,7 +33,6 @@ type Config struct {
33 33
 	NetworkDisabled bool
34 34
 	MacAddress      string
35 35
 	OnBuild         []string
36
-	SecurityOpt     []string
37 36
 }
38 37
 
39 38
 func ContainerConfigFromJob(job *engine.Job) *Config {
... ...
@@ -58,7 +57,6 @@ func ContainerConfigFromJob(job *engine.Job) *Config {
58 58
 	}
59 59
 	job.GetenvJson("ExposedPorts", &config.ExposedPorts)
60 60
 	job.GetenvJson("Volumes", &config.Volumes)
61
-	config.SecurityOpt = job.GetenvList("SecurityOpt")
62 61
 	if PortSpecs := job.GetenvList("PortSpecs"); PortSpecs != nil {
63 62
 		config.PortSpecs = PortSpecs
64 63
 	}
... ...
@@ -95,6 +95,7 @@ type HostConfig struct {
95 95
 	CapAdd          []string
96 96
 	CapDrop         []string
97 97
 	RestartPolicy   RestartPolicy
98
+	SecurityOpt     []string
98 99
 }
99 100
 
100 101
 // This is used by the create command when you want to set both the
... ...
@@ -130,6 +131,7 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
130 130
 	job.GetenvJson("PortBindings", &hostConfig.PortBindings)
131 131
 	job.GetenvJson("Devices", &hostConfig.Devices)
132 132
 	job.GetenvJson("RestartPolicy", &hostConfig.RestartPolicy)
133
+	hostConfig.SecurityOpt = job.GetenvList("SecurityOpt")
133 134
 	if Binds := job.GetenvList("Binds"); Binds != nil {
134 135
 		hostConfig.Binds = Binds
135 136
 	}
... ...
@@ -273,7 +273,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
273 273
 		MacAddress:      *flMacAddress,
274 274
 		Entrypoint:      entrypoint,
275 275
 		WorkingDir:      *flWorkingDir,
276
-		SecurityOpt:     flSecurityOpt.GetAll(),
277 276
 	}
278 277
 
279 278
 	hostConfig := &HostConfig{
... ...
@@ -294,6 +293,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
294 294
 		CapAdd:          flCapAdd.GetAll(),
295 295
 		CapDrop:         flCapDrop.GetAll(),
296 296
 		RestartPolicy:   restartPolicy,
297
+		SecurityOpt:     flSecurityOpt.GetAll(),
297 298
 	}
298 299
 
299 300
 	// When allocating stdin in attached mode, close stdin at client disconnect