To ensure we don't regress on bad --cgroup-parent paths, add some
integration tests that check that the host hasn't toppled (or suddently
started to create files in the host).
Signed-off-by: Aleksa Sarai <asarai@suse.com>
| ... | ... |
@@ -3466,6 +3466,84 @@ func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
|
| 3466 | 3466 |
} |
| 3467 | 3467 |
} |
| 3468 | 3468 |
|
| 3469 |
+// TestRunInvalidCgroupParent checks that a specially-crafted cgroup parent doesn't cause Docker to crash or start modifying /. |
|
| 3470 |
+func (s *DockerSuite) TestRunInvalidCgroupParent(c *check.C) {
|
|
| 3471 |
+ // Not applicable on Windows as uses Unix specific functionality |
|
| 3472 |
+ testRequires(c, DaemonIsLinux) |
|
| 3473 |
+ |
|
| 3474 |
+ cgroupParent := "../../../../../../../../SHOULD_NOT_EXIST" |
|
| 3475 |
+ cleanCgroupParent := "SHOULD_NOT_EXIST" |
|
| 3476 |
+ name := "cgroup-invalid-test" |
|
| 3477 |
+ |
|
| 3478 |
+ out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
|
|
| 3479 |
+ if err != nil {
|
|
| 3480 |
+ // XXX: This may include a daemon crash. |
|
| 3481 |
+ c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
|
| 3482 |
+ } |
|
| 3483 |
+ |
|
| 3484 |
+ // We expect "/SHOULD_NOT_EXIST" to not exist. If not, we have a security issue. |
|
| 3485 |
+ if _, err := os.Stat("/SHOULD_NOT_EXIST"); err == nil || !os.IsNotExist(err) {
|
|
| 3486 |
+ c.Fatalf("SECURITY: --cgroup-parent with ../../ relative paths cause files to be created in the host (this is bad) !!")
|
|
| 3487 |
+ } |
|
| 3488 |
+ |
|
| 3489 |
+ cgroupPaths := parseCgroupPaths(string(out)) |
|
| 3490 |
+ if len(cgroupPaths) == 0 {
|
|
| 3491 |
+ c.Fatalf("unexpected output - %q", string(out))
|
|
| 3492 |
+ } |
|
| 3493 |
+ id, err := getIDByName(name) |
|
| 3494 |
+ c.Assert(err, check.IsNil) |
|
| 3495 |
+ expectedCgroup := path.Join(cleanCgroupParent, id) |
|
| 3496 |
+ found := false |
|
| 3497 |
+ for _, path := range cgroupPaths {
|
|
| 3498 |
+ if strings.HasSuffix(path, expectedCgroup) {
|
|
| 3499 |
+ found = true |
|
| 3500 |
+ break |
|
| 3501 |
+ } |
|
| 3502 |
+ } |
|
| 3503 |
+ if !found {
|
|
| 3504 |
+ c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
|
|
| 3505 |
+ } |
|
| 3506 |
+} |
|
| 3507 |
+ |
|
| 3508 |
+// TestRunInvalidCgroupParent checks that a specially-crafted cgroup parent doesn't cause Docker to crash or start modifying /. |
|
| 3509 |
+func (s *DockerSuite) TestRunAbsoluteInvalidCgroupParent(c *check.C) {
|
|
| 3510 |
+ // Not applicable on Windows as uses Unix specific functionality |
|
| 3511 |
+ testRequires(c, DaemonIsLinux) |
|
| 3512 |
+ |
|
| 3513 |
+ cgroupParent := "/../../../../../../../../SHOULD_NOT_EXIST" |
|
| 3514 |
+ cleanCgroupParent := "/SHOULD_NOT_EXIST" |
|
| 3515 |
+ name := "cgroup-absolute-invalid-test" |
|
| 3516 |
+ |
|
| 3517 |
+ out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
|
|
| 3518 |
+ if err != nil {
|
|
| 3519 |
+ // XXX: This may include a daemon crash. |
|
| 3520 |
+ c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
|
| 3521 |
+ } |
|
| 3522 |
+ |
|
| 3523 |
+ // We expect "/SHOULD_NOT_EXIST" to not exist. If not, we have a security issue. |
|
| 3524 |
+ if _, err := os.Stat("/SHOULD_NOT_EXIST"); err == nil || !os.IsNotExist(err) {
|
|
| 3525 |
+ c.Fatalf("SECURITY: --cgroup-parent with /../../ garbage paths cause files to be created in the host (this is bad) !!")
|
|
| 3526 |
+ } |
|
| 3527 |
+ |
|
| 3528 |
+ cgroupPaths := parseCgroupPaths(string(out)) |
|
| 3529 |
+ if len(cgroupPaths) == 0 {
|
|
| 3530 |
+ c.Fatalf("unexpected output - %q", string(out))
|
|
| 3531 |
+ } |
|
| 3532 |
+ id, err := getIDByName(name) |
|
| 3533 |
+ c.Assert(err, check.IsNil) |
|
| 3534 |
+ expectedCgroup := path.Join(cleanCgroupParent, id) |
|
| 3535 |
+ found := false |
|
| 3536 |
+ for _, path := range cgroupPaths {
|
|
| 3537 |
+ if strings.HasSuffix(path, expectedCgroup) {
|
|
| 3538 |
+ found = true |
|
| 3539 |
+ break |
|
| 3540 |
+ } |
|
| 3541 |
+ } |
|
| 3542 |
+ if !found {
|
|
| 3543 |
+ c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
|
|
| 3544 |
+ } |
|
| 3545 |
+} |
|
| 3546 |
+ |
|
| 3469 | 3547 |
func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
|
| 3470 | 3548 |
// Not applicable on Windows as uses Unix specific functionality |
| 3471 | 3549 |
// --read-only + userns has remount issues |