This commit is contained in:
J0kkeR 2026-11-05 17:02:12 -03:00 • committed by GitHub
commit 7523d35038
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 1 deletions

View file

@ -54,6 +54,27 @@ _EXTRA_FILE_EXTRACT_TIMEOUT_S = 120
_EXTRA_FILE_MODE = 0o644
def _is_regular_login_user(uid: int) -> bool:
"""Whether ``uid`` refers to an interactive login user whose home directory
can take part in the sandbox uid-remapping flow.
System/service accounts (uid below the login range, or without a usable
home directory) must not opt in: the sandbox image's entrypoint demotes
itself to ``STRIX_HOST_UID``, and a demoted system uid ends up with an
unwritable HOME, which panics the in-container Caido sidecar
("Unable to create data directory") and silently degrades every scan.
"""
import pwd
if uid < 1000:
return False
try:
pw_dir = pwd.getpwuid(uid).pw_dir
except KeyError:
return False
return bool(pw_dir) and pw_dir not in ("/", "/nonexistent")
def _host_identity_env() -> dict[str, str]:
# Read the platform through a local so it is not narrowed to whichever OS is
# type-checking: comparing sys.platform directly makes one of these branches
@ -63,7 +84,15 @@ def _host_identity_env() -> dict[str, str]:
return {}
# Bind-mount ownership only needs mapping on Linux, where the container uid
# must match the host's.
return {"STRIX_HOST_UID": str(os.getuid()), "STRIX_HOST_GID": str(os.getgid())}
uid, gid = os.getuid(), os.getgid()
if not _is_regular_login_user(uid):
logger.warning(
"Skipping sandbox uid mapping for uid %s (system/service account): "
"bind-mounted workspace files will keep the container user's ownership",
uid,
)
return {}
return {"STRIX_HOST_UID": str(uid), "STRIX_HOST_GID": str(gid)}
def build_bind_mounts(local_sources: list[dict[str, Any]]) -> list[dict[str, Any]]:

View file

@ -0,0 +1,45 @@
import os
import sys
from types import SimpleNamespace
import pytest
from strix.runtime import session_manager
pytestmark = pytest.mark.skipif(
sys.platform != "linux", reason="sandbox uid mapping is Linux-only"
)
def _as(monkeypatch, uid: int, gid: int) -> None:
monkeypatch.setattr(os, "getuid", lambda: uid)
monkeypatch.setattr(os, "getgid", lambda: gid)
def test_system_account_uid_skips_mapping(monkeypatch):
_as(monkeypatch, 997, 980)
assert session_manager._host_identity_env() == {}
def test_uid_below_login_range_skips_mapping(monkeypatch):
_as(monkeypatch, 999, 999)
assert session_manager._host_identity_env() == {}
def test_homeless_uid_skips_mapping(monkeypatch):
_as(monkeypatch, 1500, 1500)
monkeypatch.setattr(
"pwd.getpwuid", lambda uid: SimpleNamespace(pw_dir="/nonexistent")
)
assert session_manager._host_identity_env() == {}
def test_regular_user_is_mapped(monkeypatch):
_as(monkeypatch, 1500, 1500)
monkeypatch.setattr(
"pwd.getpwuid", lambda uid: SimpleNamespace(pw_dir="/home/dev")
)
assert session_manager._host_identity_env() == {
"STRIX_HOST_UID": "1500",
"STRIX_HOST_GID": "1500",
}