Skip to content

Commit 263eee6

Browse files
committed
fix(release): verify contained interpreter links
1 parent d79dbec commit 263eee6

2 files changed

Lines changed: 52 additions & 8 deletions

File tree

‎scripts/contained-runtime-run.mjs‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
chmodSync,
77
existsSync,
88
lstatSync,
9+
readlinkSync,
910
readFileSync,
1011
readdirSync,
1112
realpathSync,
@@ -861,6 +862,9 @@ const runnerRootfsPermissionContract = Object.freeze([
861862
{ path: "/usr/local", kind: "directory", mode: 0o755 },
862863
{ path: "/usr/local/bin", kind: "directory", mode: 0o755 },
863864
{ path: "/usr/local/bin/node", kind: "file", mode: 0o555 },
865+
{ path: "/usr/local/bin/python", kind: "symlink", mode: 0o777 },
866+
{ path: "/usr/local/bin/python3", kind: "symlink", mode: 0o777 },
867+
{ path: "/usr/local/bin/python3.13", kind: "file", mode: 0o755 },
864868
{ path: "/usr/bin", kind: "directory", mode: 0o755 },
865869
{ path: "/usr/bin/setpriv", kind: "file", mode: 0o555 },
866870
{ path: "/usr/bin/bash", kind: "file", mode: 0o555 },
@@ -908,8 +912,8 @@ const runnerRootfsPermissionContract = Object.freeze([
908912
},
909913
{
910914
path: "/opt/counterlab-venv/bin/python",
911-
kind: "file",
912-
mode: 0o550,
915+
kind: "symlink",
916+
mode: 0o777,
913917
gid: 10001,
914918
},
915919
{ path: "/opt/codex", kind: "directory", mode: 0o550, gid: 10002 },
@@ -946,6 +950,12 @@ const runnerRootfsPermissionContract = Object.freeze([
946950
{ path: "/counterlab-runtime", kind: "directory", mode: 0o755 },
947951
]);
948952

953+
const runnerRootfsSymlinkContract = new Map([
954+
["/usr/local/bin/python", "python3"],
955+
["/usr/local/bin/python3", "python3.13"],
956+
["/opt/counterlab-venv/bin/python", "/usr/local/bin/python"],
957+
]);
958+
949959
export function validateContainedRunnerRootfsPermissions(entries) {
950960
if (
951961
!Array.isArray(entries) ||
@@ -988,18 +998,31 @@ function verifyContainedRunnerRootfsPermissions(plan, imageRootfsPath) {
988998
if (!plan.image.startsWith("counterlab-runner:git-")) return;
989999
validateContainedRunnerRootfsPermissions(
9901000
runnerRootfsPermissionContract.map((expected) => {
991-
const metadata = statSync(
1001+
const path =
9921002
expected.path === "/"
9931003
? imageRootfsPath
994-
: resolve(imageRootfsPath, expected.path.slice(1)),
995-
);
1004+
: resolve(imageRootfsPath, expected.path.slice(1));
1005+
const metadata = lstatSync(path);
1006+
const expectedLinkTarget = runnerRootfsSymlinkContract.get(expected.path);
1007+
if (
1008+
(expectedLinkTarget === undefined && metadata.isSymbolicLink()) ||
1009+
(expectedLinkTarget !== undefined &&
1010+
(!metadata.isSymbolicLink() ||
1011+
readlinkSync(path) !== expectedLinkTarget))
1012+
) {
1013+
throw new Error(
1014+
`contained runner rootfs symlink changed at ${expected.path}`,
1015+
);
1016+
}
9961017
return {
9971018
path: expected.path,
9981019
kind: metadata.isDirectory()
9991020
? "directory"
10001021
: metadata.isFile()
10011022
? "file"
1002-
: "other",
1023+
: metadata.isSymbolicLink()
1024+
? "symlink"
1025+
: "other",
10031026
mode: metadata.mode & 0o777,
10041027
uid: metadata.uid,
10051028
gid: metadata.gid,

‎scripts/contained-runtime.test.ts‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,27 @@ describe("contained runtime command policy", () => {
18561856
uid: 0,
18571857
gid: 0,
18581858
},
1859+
{
1860+
path: "/usr/local/bin/python",
1861+
kind: "symlink",
1862+
mode: 0o777,
1863+
uid: 0,
1864+
gid: 0,
1865+
},
1866+
{
1867+
path: "/usr/local/bin/python3",
1868+
kind: "symlink",
1869+
mode: 0o777,
1870+
uid: 0,
1871+
gid: 0,
1872+
},
1873+
{
1874+
path: "/usr/local/bin/python3.13",
1875+
kind: "file",
1876+
mode: 0o755,
1877+
uid: 0,
1878+
gid: 0,
1879+
},
18591880
{ path: "/usr/bin", kind: "directory", mode: 0o755, uid: 0, gid: 0 },
18601881
{ path: "/usr/bin/setpriv", kind: "file", mode: 0o555, uid: 0, gid: 0 },
18611882
{ path: "/usr/bin/bash", kind: "file", mode: 0o555, uid: 0, gid: 0 },
@@ -1952,8 +1973,8 @@ describe("contained runtime command policy", () => {
19521973
},
19531974
{
19541975
path: "/opt/counterlab-venv/bin/python",
1955-
kind: "file",
1956-
mode: 0o550,
1976+
kind: "symlink",
1977+
mode: 0o777,
19571978
uid: 0,
19581979
gid: 10001,
19591980
},

0 commit comments

Comments
 (0)