Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/codegen/codegen.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- **Sandbox policies no longer cross thread boundaries.** The in-process
checker was process-global while generated permission stacks were
thread-local, so one thread entering or leaving a sandbox block could
replace or clear another thread's checker. The checker is now thread-local,
and the preload layer reads it through a weak getter that remains safe when
no embedded runtime is present.
8 changes: 6 additions & 2 deletions runtime/aether_sandbox.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions runtime/aether_sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define AETHER_SANDBOX_H

#include "aether_sandbox_match.h" /* aether_net_resource, the shared matcher */
#include "utils/aether_compiler.h"

#ifdef AETHER_HAS_SANDBOX

Expand All @@ -20,8 +21,9 @@
// Returns: 1 = allowed, 0 = denied
typedef int (*aether_sandbox_check_fn)(const char* category, const char* resource);

// Global: set by compiler-generated code when inside a sandbox block
extern aether_sandbox_check_fn _aether_sandbox_checker;
// Per-thread: set by compiler-generated code when inside a sandbox block
extern AETHER_TLS_SHARED aether_sandbox_check_fn _aether_sandbox_checker;
aether_sandbox_check_fn aether_sandbox_get_checker(void);

// The checker, with an fs path resolved to where it leads first (".." and
// symlinks), so a grant for "/box/*" cannot be left through "/box/../x" or a
Expand Down
12 changes: 8 additions & 4 deletions runtime/libaether_sandbox_preload.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 65 additions & 0 deletions tests/integration/sandbox_checker_tls/harness.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions tests/integration/sandbox_checker_tls/test_sandbox_checker_tls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh
# Each thread installs and restores its own in-process sandbox checker. One
# thread leaving an enforce block must not disable another thread's policy.

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"

case "$(uname -s 2>/dev/null)" in
Linux|FreeBSD|Darwin) ;;
*)
echo " [SKIP] sandbox_checker_tls: POSIX thread harness"
exit 0 ;;
esac
if [ ! -f "$ROOT/build/libaether.a" ]; then
echo " [SKIP] sandbox_checker_tls: build/libaether.a not built"
exit 0
fi

TMP="$(cd "$(mktemp -d)" && pwd -P)"
trap 'rm -rf "$TMP"' EXIT
if ! ${CC:-cc} -std=c11 -Wall -Wextra -Werror -DAETHER_HAS_SANDBOX \
-I"$ROOT/runtime" -o "$TMP/harness" "$SCRIPT_DIR/harness.c" \
"$ROOT/build/libaether.a" -lpthread -lm 2>"$TMP/cc.err"; then
echo " [FAIL] sandbox_checker_tls: harness did not compile"
sed 's/^/ /' "$TMP/cc.err" | head -10
exit 1
fi

out="$($TMP/harness 2>&1)"
rc=$?
if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -q \
'^PASS: sandbox checker state is thread-local$'; then
echo " [PASS] sandbox checker state is thread-local"
echo "PASS: sandbox_checker_tls"
exit 0
fi

echo " [FAIL] sandbox checker state crossed threads"
printf '%s\n' "$out" | sed 's/^/ /' | head -10
echo "FAIL: sandbox_checker_tls"
exit 1