diff --git a/PUBLIC_SOURCE_EXPORT.md b/PUBLIC_SOURCE_EXPORT.md index 51919e9..674102f 100644 --- a/PUBLIC_SOURCE_EXPORT.md +++ b/PUBLIC_SOURCE_EXPORT.md @@ -1,3 +1,3 @@ # Public source export -This source snapshot was generated from the private canonical repository at revision `87aa7dda6889fd951d202754d76daaaa1e98e26b`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. +This source snapshot was generated from the private canonical repository at revision `166e10b7084c977816a75560d015da8f350c534c`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. diff --git a/PUBLIC_SOURCE_MANIFEST.json b/PUBLIC_SOURCE_MANIFEST.json index d047281..d98de3d 100644 --- a/PUBLIC_SOURCE_MANIFEST.json +++ b/PUBLIC_SOURCE_MANIFEST.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "sourceRevision": "87aa7dda6889fd951d202754d76daaaa1e98e26b", + "sourceRevision": "166e10b7084c977816a75560d015da8f350c534c", "files": [ { "path": ".dockerignore", @@ -1659,8 +1659,8 @@ }, { "path": "backend/tests/test_runner_fleet_specialize.py", - "sha256": "8d75435eb4f7b4adb52ffaff7bbb234941c382c68a4e71bdbbc3abc177aa279a", - "bytes": 186243 + "sha256": "e37f114322da2182d8448439025abe2ad772564332cff5955e93cc43d28cf45b", + "bytes": 188449 }, { "path": "backend/tests/test_runner_fleet_v2_execution_surface.py", diff --git a/backend/tests/test_runner_fleet_specialize.py b/backend/tests/test_runner_fleet_specialize.py index ce42dfe..8e08c05 100644 --- a/backend/tests/test_runner_fleet_specialize.py +++ b/backend/tests/test_runner_fleet_specialize.py @@ -1080,7 +1080,56 @@ def test_profile_state_creation_uses_effective_runner_image_owners_and_resumes( specialize._prepare_profile_state("a" * 40) config_path.write_bytes(expected) os.chmod(config_path, 0o600) + # Docker normalizes its own data-root to 0710. Rollback preserves this + # directory; preparation must resume without changing daemon-owned bytes. + dind_root.chmod(0o710) specialize._prepare_profile_state("a" * 40) + assert dind_root.stat().st_mode & 0o7777 == 0o710 + + +@pytest.mark.skipif(os.name != "posix" or os.geteuid() != 0, reason="requires POSIX root ownership") +@pytest.mark.parametrize("fault", [None, "fresh", "mode711", "mode755", "mode770", + "mode701", "special", "owner", "group", "symlink", "file", "parent_mode", + "parent_owner", "parent_group", "parent_symlink"]) +def test_dind_data_root_accepts_only_daemon_mode_in_private_root_parent( + specialize, tmp_path, monkeypatch, fault, +): + parent = tmp_path / "dind" + parent.mkdir(mode=0o700) + root = parent / "docker" + root.mkdir(mode=0o710) + monkeypatch.setattr(specialize, "DIND_STORAGE_ROOT", root) + if fault == "fresh": + root.chmod(0o700) + elif fault and fault.startswith("mode"): + root.chmod(int(fault[4:], 8)) + elif fault == "special": + root.chmod(0o1710) + elif fault in {"owner", "group"}: + os.chown(root, 1000 if fault == "owner" else 0, 1000 if fault == "group" else 0) + elif fault in {"symlink", "file"}: + root.rmdir() + if fault == "symlink": + root.symlink_to(tmp_path, target_is_directory=True) + else: + root.write_bytes(b"not a directory") + elif fault == "parent_mode": + parent.chmod(0o710) + elif fault in {"parent_owner", "parent_group"}: + os.chown(parent, 1000 if fault == "parent_owner" else 0, + 1000 if fault == "parent_group" else 0) + elif fault == "parent_symlink": + real_parent = tmp_path / "real-dind" + parent.rename(real_parent) + parent.symlink_to(real_parent, target_is_directory=True) + if fault in {None, "fresh"}: + specialize._trusted_dind_data_root() + if fault is None: + with pytest.raises(specialize.RunnerFleetSpecializeError, match="path_untrusted"): + specialize._trusted_directory(root) + else: + with pytest.raises(specialize.RunnerFleetSpecializeError, match="path_untrusted"): + specialize._trusted_dind_data_root() def _mounts(specialize, service):