1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #29984 from jmzwcn/issueNNP

[feature]: add daemon flag to set no_new_priv as default for unprivileged containers
This commit is contained in:
Anusha Ragunathan 2017-02-17 11:43:43 -08:00 committed by GitHub
commit 6dd2a82458
9 changed files with 67 additions and 3 deletions

View file

@ -30,6 +30,7 @@ type Config struct {
InitPath string `json:"init-path,omitempty"`
SeccompProfile string `json:"seccomp-profile,omitempty"`
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
NoNewPrivileges bool `json:"no-new-privileges,omitempty"`
}
// BridgeConfig stores all the bridge driver specific

View file

@ -182,7 +182,7 @@ func (daemon *Daemon) generateHostname(id string, config *containertypes.Config)
func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
container.Lock()
defer container.Unlock()
return parseSecurityOpt(container, hostConfig)
return daemon.parseSecurityOpt(container, hostConfig)
}
func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {

View file

@ -66,6 +66,10 @@ func (daemon *Daemon) cleanupMountsByID(id string) error {
return nil
}
func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
return parseSecurityOpt(container, hostConfig)
}
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
//Since config.SecurityOpt is specifically defined as a "List of string values to
//customize labels for MLs systems, such as SELinux"

View file

@ -162,6 +162,11 @@ func getBlkioWeightDevices(config containertypes.Resources) ([]specs.WeightDevic
return blkioWeightDevices, nil
}
func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
container.NoNewPrivileges = daemon.configStore.NoNewPrivileges
return parseSecurityOpt(container, hostConfig)
}
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
var (
labelOpts []string
@ -193,6 +198,12 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
container.AppArmorProfile = con[1]
case "seccomp":
container.SeccompProfile = con[1]
case "no-new-privileges":
noNewPrivileges, err := strconv.ParseBool(con[1])
if err != nil {
return fmt.Errorf("invalid --security-opt 2: %q", opt)
}
container.NoNewPrivileges = noNewPrivileges
default:
return fmt.Errorf("invalid --security-opt 2: %q", opt)
}

View file

@ -180,6 +180,35 @@ func TestParseSecurityOpt(t *testing.T) {
}
}
func TestParseNNPSecurityOptions(t *testing.T) {
daemon := &Daemon{
configStore: &config.Config{NoNewPrivileges: true},
}
container := &container.Container{}
config := &containertypes.HostConfig{}
// test NNP when "daemon:true" and "no-new-privileges=false""
config.SecurityOpt = []string{"no-new-privileges=false"}
if err := daemon.parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected daemon.parseSecurityOpt error: %v", err)
}
if container.NoNewPrivileges {
t.Fatalf("container.NoNewPrivileges should be FALSE: %v", container.NoNewPrivileges)
}
// test NNP when "daemon:false" and "no-new-privileges=true""
daemon.configStore.NoNewPrivileges = false
config.SecurityOpt = []string{"no-new-privileges=true"}
if err := daemon.parseSecurityOpt(container, config); err != nil {
t.Fatalf("Unexpected daemon.parseSecurityOpt error: %v", err)
}
if !container.NoNewPrivileges {
t.Fatalf("container.NoNewPrivileges should be TRUE: %v", container.NoNewPrivileges)
}
}
func TestNetworkOptions(t *testing.T) {
daemon := &Daemon{}
dconfigCorrect := &config.Config{

View file

@ -52,6 +52,10 @@ func getBlkioWeightDevices(config *containertypes.HostConfig) ([]blkiodev.Weight
return nil, nil
}
func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
return parseSecurityOpt(container, hostConfig)
}
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
return nil
}

View file

@ -70,6 +70,7 @@ Options:
--max-concurrent-uploads int Set the max concurrent uploads for each push (default 5)
--metrics-addr string Set address and port to serve the metrics api (default "")
--mtu int Set the containers network MTU
--no-new-privileges Disable container processes from gaining new privileges
--oom-score-adjust int Set the oom_score_adj for the daemon (default -500)
-p, --pidfile string Path to use for daemon PID file (default "/var/run/docker.pid")
--raw-logs Full timestamps without ANSI coloring
@ -1190,6 +1191,7 @@ This is a full example of the allowed configuration options on Linux:
"seccomp-profile": "",
"insecure-registries": [],
"disable-legacy-registry": false,
"no-new-privileges": false,
"default-runtime": "runc",
"oom-score-adjust": -500,
"runtimes": {

View file

@ -630,7 +630,7 @@ with the same logic -- if the original volume was specified with a name it will
--security-opt="label=level:LEVEL" : Set the label level for the container
--security-opt="label=disable" : Turn off label confinement for the container
--security-opt="apparmor=PROFILE" : Set the apparmor profile to be applied to the container
--security-opt="no-new-privileges" : Disable container processes from gaining new privileges
--security-opt="no-new-privileges:true|false" : Disable/enable container processes from gaining new privileges
--security-opt="seccomp=unconfined" : Turn off seccomp confinement for the container
--security-opt="seccomp=profile.json": White listed syscalls seccomp Json file to be used as a seccomp filter

View file

@ -1140,12 +1140,25 @@ func (s *DockerSuite) TestRunSeccompDefaultProfileNS(c *check.C) {
}
}
// TestRunNoNewPrivSetuid checks that --security-opt=no-new-privileges prevents
// TestRunNoNewPrivSetuid checks that --security-opt='no-new-privileges=true' prevents
// effective uid transtions on executing setuid binaries.
func (s *DockerSuite) TestRunNoNewPrivSetuid(c *check.C) {
testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
ensureNNPTest(c)
// test that running a setuid binary results in no effective uid transition
icmd.RunCommand(dockerBinary, "run", "--security-opt", "no-new-privileges=true", "--user", "1000",
"nnp-test", "/usr/bin/nnp-test").Assert(c, icmd.Expected{
Out: "EUID=1000",
})
}
// TestLegacyRunNoNewPrivSetuid checks that --security-opt=no-new-privileges prevents
// effective uid transtions on executing setuid binaries.
func (s *DockerSuite) TestLegacyRunNoNewPrivSetuid(c *check.C) {
testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
ensureNNPTest(c)
// test that running a setuid binary results in no effective uid transition
icmd.RunCommand(dockerBinary, "run", "--security-opt", "no-new-privileges", "--user", "1000",
"nnp-test", "/usr/bin/nnp-test").Assert(c, icmd.Expected{