-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Replace Cgroup Parent and Name fields by CgroupsPath #497
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 |
|---|---|---|
|
|
@@ -94,11 +94,10 @@ func getCgroupRoot() (string, error) { | |
| } | ||
|
|
||
| type cgroupData struct { | ||
| root string | ||
| parent string | ||
| name string | ||
| config *configs.Cgroup | ||
| pid int | ||
| root string | ||
| innerPath string | ||
| config *configs.Cgroup | ||
| pid int | ||
| } | ||
|
|
||
| func (m *Manager) Apply(pid int) (err error) { | ||
|
|
@@ -267,45 +266,26 @@ func getCgroupPath(c *configs.Cgroup) (string, error) { | |
| return d.path("devices") | ||
| } | ||
|
|
||
| // pathClean makes a path safe for use with filepath.Join. This is done by not | ||
| // only cleaning the path, but also (if the path is relative) adding a leading | ||
| // '/' and cleaning it (then removing the leading '/'). This ensures that a | ||
| // path resulting from prepending another path will always resolve to lexically | ||
| // be a subdirectory of the prefixed path. This is all done lexically, so paths | ||
| // that include symlinks won't be safe as a result of using pathClean. | ||
| func pathClean(path string) string { | ||
| // Ensure that all paths are cleaned (especially problematic ones like | ||
| // "/../../../../../" which can cause lots of issues). | ||
| path = filepath.Clean(path) | ||
|
|
||
| // If the path isn't absolute, we need to do more processing to fix paths | ||
| // such as "../../../../<etc>/some/path". We also shouldn't convert absolute | ||
| // paths to relative ones. | ||
| if !filepath.IsAbs(path) { | ||
| path = filepath.Clean(string(os.PathSeparator) + path) | ||
| // This can't fail, as (by definition) all paths are relative to root. | ||
| path, _ = filepath.Rel(string(os.PathSeparator), path) | ||
| } | ||
|
|
||
| // Clean the path again for good measure. | ||
| return filepath.Clean(path) | ||
| } | ||
|
|
||
| func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) { | ||
| root, err := getCgroupRoot() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // Clean the parent slice path. | ||
| c.Parent = pathClean(c.Parent) | ||
| if (c.Name != "" || c.Parent != "") && c.Path != "" { | ||
| return nil, fmt.Errorf("cgroup: either Path or Name and Parent should be used") | ||
| } | ||
|
|
||
| innerPath := c.Path | ||
| if innerPath == "" { | ||
| innerPath = filepath.Join(c.Parent, c.Name) | ||
| } | ||
|
|
||
| return &cgroupData{ | ||
|
Member
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. If cgroup data is not used between systemd and fs we could remove the name and parent fields here and only hold the joined "path" if that makes sense |
||
| root: root, | ||
| parent: c.Parent, | ||
| name: c.Name, | ||
| config: c, | ||
| pid: pid, | ||
| root: root, | ||
| innerPath: c.Path, | ||
| config: c, | ||
| pid: pid, | ||
| }, nil | ||
| } | ||
|
|
||
|
|
@@ -333,19 +313,18 @@ func (raw *cgroupData) path(subsystem string) (string, error) { | |
| return "", err | ||
| } | ||
|
|
||
| cgPath := filepath.Join(raw.parent, raw.name) | ||
| // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. | ||
| if filepath.IsAbs(cgPath) { | ||
| if filepath.IsAbs(raw.innerPath) { | ||
| // Sometimes subsystems can be mounted togethger as 'cpu,cpuacct'. | ||
| return filepath.Join(raw.root, filepath.Base(mnt), cgPath), nil | ||
| return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil | ||
| } | ||
|
|
||
| parentPath, err := raw.parentPath(subsystem, mnt, root) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
|
||
| return filepath.Join(parentPath, cgPath), nil | ||
| return filepath.Join(parentPath, raw.innerPath), nil | ||
| } | ||
|
|
||
| func (raw *cgroupData) join(subsystem string) (string, error) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ import ( | |
| "github.com/opencontainers/runc/libcontainer/cgroups" | ||
| "github.com/opencontainers/runc/libcontainer/configs" | ||
| "github.com/opencontainers/runc/libcontainer/seccomp" | ||
| libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" | ||
| "github.com/opencontainers/specs" | ||
| ) | ||
|
|
||
|
|
@@ -326,13 +327,22 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount { | |
| } | ||
|
|
||
| func createCgroupConfig(name string, spec *specs.LinuxSpec) (*configs.Cgroup, error) { | ||
| myCgroupPath, err := cgroups.GetThisCgroupDir("devices") | ||
| if err != nil { | ||
| return nil, err | ||
| var ( | ||
| err error | ||
| myCgroupPath string | ||
| ) | ||
|
|
||
| if spec.Linux.CgroupsPath != nil { | ||
| myCgroupPath = libcontainerUtils.CleanPath(*spec.Linux.CgroupsPath) | ||
| } else { | ||
| myCgroupPath, err = cgroups.GetThisCgroupDir("devices") | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| } | ||
|
|
||
| c := &configs.Cgroup{ | ||
| Name: name, | ||
| Parent: myCgroupPath, | ||
| Path: filepath.Join(myCgroupPath, name), | ||
|
Member
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. I don't think you need to do a join here with name right?
Contributor
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. it depends, if I have a bundle named Do we want to use Atm the code produce the former; if we want the later, I'm not sure what is the use for name.
Member
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. ok |
||
| Resources: &configs.Resources{}, | ||
| } | ||
| c.Resources.AllowedDevices = allowedDevices | ||
|
|
||
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.
NACK on removing this. It fixes a security vulnerability. Please use this function to clean paths that need to be scoped to a mountpoint, not
filepath.Clean.EDIT: Ah, you've just moved it. Still NACK, moving it means that Docker will have a security regression.
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 should have noted that, yes.
What about making it a public method within the libcontainer/utils package?
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.
SGTM. There are probably some other places where we aren't cleaning paths properly.