Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NoNewPrivileges #557

Merged
merged 3 commits into from
Feb 16, 2016
Merged

Conversation

mrunalp
Copy link
Contributor

@mrunalp mrunalp commented Feb 15, 2016

Support NoNewPrivileges for additional security in containers.

@mrunalp
Copy link
Contributor Author

mrunalp commented Feb 15, 2016

@LK4D4 @crosbymichael ping
cc: @rhatdan

@@ -300,6 +301,7 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
config.Sysctl = spec.Linux.Sysctl
config.ProcessLabel = spec.Linux.SelinuxProcessLabel
config.AppArmorProfile = spec.Linux.ApparmorProfile
config.NoNewPrivileges = spec.Linux.NoNewPrivileges
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a spec update PR for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was pulled in a previous spec update.

@rhatdan
Copy link
Contributor

rhatdan commented Feb 15, 2016

This looks got to me. Need to get this into Docker ASAP, since it really helps people running non privileged work loads. Eliminates a lot of worry about contained non priv processes getting access to setuid or setfcap files.

@@ -171,6 +171,9 @@ type Config struct {
// A default action to be taken if no rules match is also given.
Seccomp *Seccomp `json:"seccomp"`

// NoNewPrivileges controls whether processes in the container can gain additional privileges.
NoNewPrivileges bool `json:"nonewprivileges"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a problem in this PR.
For json property names, we have nonewprivileges and noNewPrivileges and no_new_privileges in code, looks like we don't have code style for that yet, should we change them for consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sticking to whatever style we have in each repo for now :/

@mrunalp
Copy link
Contributor Author

mrunalp commented Feb 16, 2016

Updated.

@rhatdan
Copy link
Contributor

rhatdan commented Feb 16, 2016

Are we sure this work? Can you still apply seccomp rules after you have set NO_NEW_PRIVS? I thought I heard someone say that you could not.

@@ -109,6 +113,11 @@ func (l *linuxStandardInit) Init() error {
if err := syncParentReady(l.pipe); err != nil {
return err
}
if l.config.Config.NoNewPrivileges {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's no reason to place it after syncParentReady (like syncParentReady might break it), I'd prefer to place it before. Go likes to create new processes each time you do a syscall, which is the whole point of late cgroup apply (applying cgroups as late as possible means we're less likely to hit our resource limits or add any overhead during setup).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it above the sync.

@cyphar
Copy link
Member

cyphar commented Feb 16, 2016

@rhatdan I don't think that's right, if I'm reading this LWN article correctly:

Lutomirski also notes that a sandbox will be much less useful if execve() has to fail when there is any kind of security transition, as Cox suggested. The presence of a policy on a particular binary would make that binary unusable from within a sandbox, no matter what the policy is. A better solution, Lutomirski said, is to set the no_new_privs bit, then set up a sandbox (using Drewry's seccomp system call filtering for example), then execute the binary:

If you want a sandbox, call PR_SET_NO_NEW_PRIVS, then enable seccomp (or whatever) to disable ptrace, evil file access, connections on unix sockets that authenticate via uid, etc.

If you read the actual code (from kernel/seccomp.c), we have to have CAP_SYS_ADMIN while setting this up. This is fine because we drop capabilities in finalizeNamespace, which is after we enable seccomp:

    /*
     * Installing a seccomp filter requires that the task has
     * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.
     * This avoids scenarios where unprivileged tasks can affect the
     * behavior of privileged children.
     */
    if (!task_no_new_privs(current) &&
        security_capable_noaudit(current_cred(), current_user_ns(),
                     CAP_SYS_ADMIN) != 0)
        return ERR_PTR(-EACCES);

So I'm fairly sure this should work perfectly fine.

@rhatdan
Copy link
Contributor

rhatdan commented Feb 16, 2016

Great. I am probably misremembering.

@mrunalp
Copy link
Contributor Author

mrunalp commented Feb 16, 2016

Yes, I had looked at libseccomp earlier and it makes the call as well
https://github.com/seccomp/libseccomp/blob/7f3ae6e6a12390bd38f0787b242f60c47ad076c3/src/system.c#L75

@mrunalp
Copy link
Contributor Author

mrunalp commented Feb 16, 2016

I checked that there is no harm in this getting called twice but prctl itself could get blocked by seccomp so makes sense to move this before seccomp.

@crosbymichael
Copy link
Member

LGTM

1 similar comment
@LK4D4
Copy link
Contributor

LK4D4 commented Feb 16, 2016

LGTM

LK4D4 added a commit that referenced this pull request Feb 16, 2016
Add support for NoNewPrivileges
@LK4D4 LK4D4 merged commit 533ee4d into opencontainers:master Feb 16, 2016
stefanberger pushed a commit to stefanberger/runc that referenced this pull request Sep 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants