This fixes a security vulnerability in Docker, which can cause a DoS
under certain circumstances. This is from the hotfix branch, so the
vendored commit is actually bf899fef451956be4abd63de6d6141d9f9096a02 in
runc master.
Signed-off-by: Aleksa Sarai <asarai@suse.com>
| ... | ... |
@@ -57,7 +57,7 @@ clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf |
| 57 | 57 |
clone git github.com/jfrazelle/go v1.5.1-1 |
| 58 | 58 |
clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c |
| 59 | 59 |
|
| 60 |
-clone git github.com/opencontainers/runc 47e3f834d73e76bc2a6a585b48d2a93325b34979 # libcontainer |
|
| 60 |
+clone git github.com/opencontainers/runc f36b00aa12b3cb4e9c42506059fce4145cfbd626 # libcontainer |
|
| 61 | 61 |
clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1 |
| 62 | 62 |
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json) |
| 63 | 63 |
clone git github.com/coreos/go-systemd v4 |
| ... | ... |
@@ -230,12 +230,39 @@ func (m *Manager) GetPids() ([]int, error) {
|
| 230 | 230 |
return cgroups.GetPids(dir) |
| 231 | 231 |
} |
| 232 | 232 |
|
| 233 |
+// pathClean makes a path safe for use with filepath.Join. This is done by not |
|
| 234 |
+// only cleaning the path, but also (if the path is relative) adding a leading |
|
| 235 |
+// '/' and cleaning it (then removing the leading '/'). This ensures that a |
|
| 236 |
+// path resulting from prepending another path will always resolve to lexically |
|
| 237 |
+// be a subdirectory of the prefixed path. This is all done lexically, so paths |
|
| 238 |
+// that include symlinks won't be safe as a result of using pathClean. |
|
| 239 |
+func pathClean(path string) string {
|
|
| 240 |
+ // Ensure that all paths are cleaned (especially problematic ones like |
|
| 241 |
+ // "/../../../../../" which can cause lots of issues). |
|
| 242 |
+ path = filepath.Clean(path) |
|
| 243 |
+ |
|
| 244 |
+ // If the path isn't absolute, we need to do more processing to fix paths |
|
| 245 |
+ // such as "../../../../<etc>/some/path". We also shouldn't convert absolute |
|
| 246 |
+ // paths to relative ones. |
|
| 247 |
+ if !filepath.IsAbs(path) {
|
|
| 248 |
+ path = filepath.Clean(string(os.PathSeparator) + path) |
|
| 249 |
+ // This can't fail, as (by definition) all paths are relative to root. |
|
| 250 |
+ path, _ = filepath.Rel(string(os.PathSeparator), path) |
|
| 251 |
+ } |
|
| 252 |
+ |
|
| 253 |
+ // Clean the path again for good measure. |
|
| 254 |
+ return filepath.Clean(path) |
|
| 255 |
+} |
|
| 256 |
+ |
|
| 233 | 257 |
func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
|
| 234 | 258 |
root, err := getCgroupRoot() |
| 235 | 259 |
if err != nil {
|
| 236 | 260 |
return nil, err |
| 237 | 261 |
} |
| 238 | 262 |
|
| 263 |
+ // Clean the parent slice path. |
|
| 264 |
+ c.Parent = pathClean(c.Parent) |
|
| 265 |
+ |
|
| 239 | 266 |
return &cgroupData{
|
| 240 | 267 |
root: root, |
| 241 | 268 |
parent: c.Parent, |
| ... | ... |
@@ -4,6 +4,7 @@ package fs |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 | 6 |
"bytes" |
| 7 |
+ "fmt" |
|
| 7 | 8 |
"io/ioutil" |
| 8 | 9 |
"os" |
| 9 | 10 |
"path/filepath" |
| ... | ... |
@@ -95,6 +96,10 @@ func (s *CpusetGroup) ensureParent(current, root string) error {
|
| 95 | 95 |
if filepath.Clean(parent) == root {
|
| 96 | 96 |
return nil |
| 97 | 97 |
} |
| 98 |
+ // Avoid infinite recursion. |
|
| 99 |
+ if parent == current {
|
|
| 100 |
+ return fmt.Errorf("cpuset: cgroup parent path outside cgroup root")
|
|
| 101 |
+ } |
|
| 98 | 102 |
if err := s.ensureParent(parent, root); err != nil {
|
| 99 | 103 |
return err |
| 100 | 104 |
} |