-
Notifications
You must be signed in to change notification settings - Fork 2.2k
nsenter: guarantee correct user namespace ordering #977
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #ifndef NSENTER_NAMESPACE_H | ||
| #define NSENTER_NAMESPACE_H | ||
|
|
||
| #ifndef _GNU_SOURCE | ||
| # define _GNU_SOURCE | ||
| #endif | ||
| #include <sched.h> | ||
|
|
||
| /* All of these are taken from include/uapi/linux/sched.h */ | ||
| #ifndef CLONE_NEWNS | ||
| # define CLONE_NEWNS 0x00020000 /* New mount namespace group */ | ||
| #endif | ||
| #ifndef CLONE_NEWCGROUP | ||
| # define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ | ||
| #endif | ||
| #ifndef CLONE_NEWUTS | ||
| # define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ | ||
| #endif | ||
| #ifndef CLONE_NEWIPC | ||
| # define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ | ||
| #endif | ||
| #ifndef CLONE_NEWUSER | ||
| # define CLONE_NEWUSER 0x10000000 /* New user namespace */ | ||
| #endif | ||
| #ifndef CLONE_NEWPID | ||
| # define CLONE_NEWPID 0x20000000 /* New pid namespace */ | ||
| #endif | ||
| #ifndef CLONE_NEWNET | ||
| # define CLONE_NEWNET 0x40000000 /* New network namespace */ | ||
| #endif | ||
|
|
||
| #endif /* NSENTER_NAMESPACE_H */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,7 @@ func TestNsenterValidPaths(t *testing.T) { | |
|
|
||
| namespaces := []string{ | ||
| // join pid ns of the current process | ||
| fmt.Sprintf("/proc/%d/ns/pid", os.Getpid()), | ||
| fmt.Sprintf("pid:/proc/%d/ns/pid", os.Getpid()), | ||
| } | ||
| cmd := &exec.Cmd{ | ||
| Path: os.Args[0], | ||
|
|
@@ -87,7 +87,47 @@ func TestNsenterInvalidPaths(t *testing.T) { | |
|
|
||
| namespaces := []string{ | ||
| // join pid ns of the current process | ||
| fmt.Sprintf("/proc/%d/ns/pid", -1), | ||
| fmt.Sprintf("pid:/proc/%d/ns/pid", -1), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should try "pid:/proc/%d/ns/net" here to test the ns path validation?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, good idea. I've added an extra test for this, so we can test both cases (invalid type specifier and invalid path). |
||
| } | ||
| cmd := &exec.Cmd{ | ||
| Path: os.Args[0], | ||
| Args: args, | ||
| ExtraFiles: []*os.File{child}, | ||
| Env: []string{"_LIBCONTAINER_INITPIPE=3"}, | ||
| } | ||
|
|
||
| if err := cmd.Start(); err != nil { | ||
| t.Fatal(err) | ||
| } | ||
| // write cloneFlags | ||
| r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) | ||
| r.AddData(&libcontainer.Int32msg{ | ||
| Type: libcontainer.CloneFlagsAttr, | ||
| Value: uint32(syscall.CLONE_NEWNET), | ||
| }) | ||
| r.AddData(&libcontainer.Bytemsg{ | ||
| Type: libcontainer.NsPathsAttr, | ||
| Value: []byte(strings.Join(namespaces, ",")), | ||
| }) | ||
| if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| if err := cmd.Wait(); err == nil { | ||
| t.Fatalf("nsenter exits with a zero exit status") | ||
| } | ||
| } | ||
|
|
||
| func TestNsenterIncorrectPathType(t *testing.T) { | ||
| args := []string{"nsenter-exec"} | ||
| parent, child, err := newPipe() | ||
| if err != nil { | ||
| t.Fatalf("failed to create pipe %v", err) | ||
| } | ||
|
|
||
| namespaces := []string{ | ||
| // join pid ns of the current process | ||
| fmt.Sprintf("net:/proc/%d/ns/pid", os.Getpid()), | ||
| } | ||
| cmd := &exec.Cmd{ | ||
| Path: os.Args[0], | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm still not sure if setting namespace type here is necessary. Seems like something we do with no gain since the namespace type is already "known" (implicitly) ( and result in more code )
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't though. All we have is a path from the perspective of
nsenter. And we need this for the code in #976 (we only can double fork if we've joined a PID namespace). It addition, it's added safety to make sure that we're not accidentally screwing up the paths.