mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-19 04:59:28 +00:00
search-with-proof: root-no-userns isolation mode for gVisor
The kube-ax probe showed bwrap cannot map uids in gVisor as an unprivileged user. As root (gVisor is the outer boundary) the sandbox uses pid/ipc/uts/net/mount namespaces without a user namespace and drops the artefact to its own uid via setpriv; the mode is recorded. The probe reports each namespace kind separately. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e6871fef9a
commit
03857c9bec
@@ -20,7 +20,7 @@ import stat
|
||||
import tempfile
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
from dataclasses import asdict, dataclass
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -61,6 +61,8 @@ class SideRecord:
|
||||
ready_seconds: float = 0.0
|
||||
run_seconds: float = 0.0
|
||||
scratch_peak_bytes: int = 0
|
||||
isolation_mode: str = field(default_factory=_sandbox.isolation_mode)
|
||||
chromium_no_sandbox: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -69,6 +71,8 @@ class VerificationRecord:
|
||||
sides: tuple[SideRecord, ...]
|
||||
elapsed_seconds: float
|
||||
reason: str
|
||||
isolation_mode: str = field(default_factory=_sandbox.isolation_mode)
|
||||
chromium_no_sandbox: bool = False
|
||||
|
||||
|
||||
def _tree(root: Path) -> str:
|
||||
@@ -125,7 +129,15 @@ def _side(side: Side, demo: Path, family: str, timeout: int, browser: BrowserExe
|
||||
|
||||
def record(outcome: str, reason: str) -> SideRecord:
|
||||
return SideRecord(
|
||||
outcome, tuple(observations), time.monotonic() - started, reason, timings["build"], timings["ready"], timings["run"], disk_peak
|
||||
outcome,
|
||||
tuple(observations),
|
||||
time.monotonic() - started,
|
||||
reason,
|
||||
timings["build"],
|
||||
timings["ready"],
|
||||
timings["run"],
|
||||
disk_peak,
|
||||
chromium_no_sandbox=bool(getattr(browser, "no_sandbox", False)),
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -170,7 +182,14 @@ def _side(side: Side, demo: Path, family: str, timeout: int, browser: BrowserExe
|
||||
app_env = oracle.prepare(canary)
|
||||
app_scratch = canary.root if family == "command" else root / "app"
|
||||
app_scratch.mkdir(exist_ok=True)
|
||||
app_mounts = {**mounts, "/fixture": canary.root}
|
||||
fixture = canary.root
|
||||
if _sandbox.isolation_mode() == "root-no-userns" and family != "command":
|
||||
# Observer originals remain private. Only the app gets a
|
||||
# read-only copy of the fixtures its interface requires.
|
||||
fixture = shutil.copytree(canary.root, root / "app-fixture")
|
||||
for path in [fixture, *fixture.rglob("*")]:
|
||||
path.chmod(0o555 if path.is_dir() else 0o444)
|
||||
app_mounts = {**mounts, "/fixture": fixture}
|
||||
ready = timed(
|
||||
"ready",
|
||||
_sandbox.run,
|
||||
@@ -262,7 +281,13 @@ def verify(
|
||||
outcome, reason = "demonstrated", "owned effect in 3/3 affected runs and 0/3 safe runs"
|
||||
else:
|
||||
outcome, reason = "inconclusive", "no consistent differential effect"
|
||||
return VerificationRecord(outcome, sides, time.monotonic() - started, reason)
|
||||
return VerificationRecord(
|
||||
outcome,
|
||||
sides,
|
||||
time.monotonic() - started,
|
||||
reason,
|
||||
chromium_no_sandbox=bool(getattr(browser, "no_sandbox", False)),
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
Reference in New Issue
Block a user