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

Handle running nested in a user namespace #458

Merged
merged 1 commit into from
Jan 11, 2016

Conversation

hallyn
Copy link
Contributor

@hallyn hallyn commented Jan 7, 2016

Therefore check for that. This is a step to being able to run docker/runc containers inside a user namespaced container.

No change in behavior when running in the initial user namespace.

Signed-off-by: Serge Hallyn serge.hallyn@ubuntu.com

@hallyn
Copy link
Contributor Author

hallyn commented Jan 7, 2016

Note there is no technical or security reason why these could not be allowed in a user namespace, but the kernel patch to change that was rejected by the kernel cgroups maintainer.

@mrunalp
Copy link
Contributor

mrunalp commented Jan 8, 2016

We had a related discussion in the OCI weekly call yesterday. I proposed separation of the devices cgroup configuration from the other device configuration. That way we can just exclude the device cgroup manipulation when nesting. However, this can also work before that lands. Your commit is missing the actual Godep vendored files, though. Thanks!

@hallyn
Copy link
Contributor Author

hallyn commented Jan 8, 2016

On Thu, Jan 07, 2016 at 05:48:57PM -0800, Mrunal Patel wrote:

Your commit is missing the actual Godep vendored files, though. Thanks!

yeah sorry wasn't sure what the right step is.

Should I 'go get' the code with runc/Godeps/_workspace as my GOPATH ?

@hqhq
Copy link
Contributor

hqhq commented Jan 8, 2016

@hallyn runc uses godep, you can follow the instruction from: https://github.com/tools/godep#add-a-dependency

@hallyn hallyn changed the title Cannot update devices cgroups when already in a user namespace Handle running nested in a user namespace Jan 8, 2016
@hallyn hallyn force-pushed the userns branch 3 times, most recently from 51b08c4 to 9ca6225 Compare January 8, 2016 08:55
@dqminh
Copy link
Contributor

dqminh commented Jan 8, 2016

@hallyn is it possible to move the required functions to another small-ish package ? Importing all the lxd/shared dependencies seem rather expensive for this small change.

@hallyn
Copy link
Contributor Author

hallyn commented Jan 8, 2016

Hi - certainly possible :) Ideally it would be defined in libcontainer and
reused in docker, which also needs to use this check at two places.

(see moby/moby#19182)

I'll go ahead and update both requests with something shared that works.

@mrunalp
Copy link
Contributor

mrunalp commented Jan 8, 2016

@hallyn
Copy link
Contributor Author

hallyn commented Jan 8, 2016

@mrunalp

I went with system instead of util, since it is linux-specific. Should I move
it to utils instead?

@mrunalp
Copy link
Contributor

mrunalp commented Jan 8, 2016

@hallyn I am fine with system.


line := string(l)
var a, b, c int64
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a comment that this function assumes that uid_map has been written in the new user namespace (which is a fair assumption)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On Fri, Jan 08, 2016 at 11:51:26AM -0800, Mrunal Patel wrote:

+func RunningInUserNS() bool {

  • file, err := os.Open("/proc/self/uid_map")
  • if err != nil {
  •   return false
    
  • }
  • defer file.Close()
  • buf := bufio.NewReader(file)
  • l, _, err := buf.ReadLine()
  • if err != nil {
  •   return false
    
  • }
  • line := string(l)
  • var a, b, c int64
  • fmt.Sscanf(line, "%d %d %d", &a, &b, &c)

Can we add a comment that this function assumes that uid_map has been written in the new user namespace (which is a fair assumption)?

I don't understand what you mean. The file is a procfile, served by the
kernel. If it's not there we assume the kernel doesn't support user
namespaces and return false at the top.

Happy to add a comment but not sure what you are referring to.

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant that we are checking for the default values in the uid_map file to check user namespace is in use. So the assumption is that new values that differ from the default values in that file have been written. Adding this is discretionary but I think might clarify the behavior. What do you think?

On Jan 8, 2016, at 11:55 AM, Serge Hallyn notifications@github.com wrote:

In libcontainer/system/linux.go:

+func RunningInUserNS() bool {

  • file, err := os.Open("/proc/self/uid_map")
  • if err != nil {
  •   return false
    
  • }
  • defer file.Close()
  • buf := bufio.NewReader(file)
  • l, _, err := buf.ReadLine()
  • if err != nil {
  •   return false
    
  • }
  • line := string(l)
  • var a, b, c int64
  • fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
    On Fri, Jan 08, 2016 at 11:51:26AM -0800, Mrunal Patel wrote: > +func RunningInUserNS() bool { > + file, err := os.Open("/proc/self/uid_map") > + if err != nil { > + return false > + } > + defer file.Close() > + > + buf := bufio.NewReader(file) > + l, _, err := buf.ReadLine() > + if err != nil { > + return false > + } > + > + line := string(l) > + var a, b, c int64 > + fmt.Sscanf(line, "%d %d %d", &a, &b, &c) Can we add a comment that this function assumes that uid_map has been written in the new user namespace (which is a fair assumption)?
    I don't understand what you mean. The file is a procfile, served by the kernel. If it's not there we assume the kernel doesn't support user namespaces and return false at the top. Happy to add a comment but not sure what you are referring to.

    Reply to this email directly or view it on GitHub.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On Fri, Jan 08, 2016 at 12:47:24PM -0800, Mrunal Patel wrote:

+func RunningInUserNS() bool {

  • file, err := os.Open("/proc/self/uid_map")
  • if err != nil {
  •   return false
    
  • }
  • defer file.Close()
  • buf := bufio.NewReader(file)
  • l, _, err := buf.ReadLine()
  • if err != nil {
  •   return false
    
  • }
  • line := string(l)
  • var a, b, c int64
  • fmt.Sscanf(line, "%d %d %d", &a, &b, &c)

I meant that we are checking for the default values in the uid_map file to check user namespace is in use. So the assumption is that new values that differ from the default values in that file have been written. Adding this is discretionary but I think might clarify the behavior. What do you think?

Gotcha - will do

When we launch a container in a new user namespace, we cannot create
devices, so we bind mount the host's devices into place instead.

If we are running in a user namespace (i.e. nested in a container),
then we need to do the same thing.  Add a function to detect that
and check for it before doing mknod.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
---
 Changelog - add a comment clarifying what's going on with the
	     uidmap file.
@hallyn
Copy link
Contributor Author

hallyn commented Jan 8, 2016

Is travis being fragile, or am I just failing to see what i did wrong?

@mrunalp
Copy link
Contributor

mrunalp commented Jan 8, 2016

@hallyn Thanks! LGTM
ping @crosbymichael @LK4D4

@dqminh
Copy link
Contributor

dqminh commented Jan 11, 2016

LGTM

mrunalp pushed a commit that referenced this pull request Jan 11, 2016
Handle running nested in a user namespace
@mrunalp mrunalp merged commit d431081 into opencontainers:master Jan 11, 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.

5 participants