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:
commit
6dd2a82458
9 changed files with 67 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Add table
Reference in a new issue