@anthropic-ai/sandbox-runtime 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -10
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/sandbox/generate-seccomp-filter.d.ts +21 -29
- package/dist/sandbox/generate-seccomp-filter.d.ts.map +1 -1
- package/dist/sandbox/generate-seccomp-filter.js +36 -325
- package/dist/sandbox/generate-seccomp-filter.js.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.d.ts +22 -21
- package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.js +102 -82
- package/dist/sandbox/linux-sandbox-utils.js.map +1 -1
- package/dist/sandbox/macos-sandbox-utils.d.ts +1 -0
- package/dist/sandbox/macos-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/macos-sandbox-utils.js +80 -3
- package/dist/sandbox/macos-sandbox-utils.js.map +1 -1
- package/dist/sandbox/sandbox-config.d.ts +16 -0
- package/dist/sandbox/sandbox-config.d.ts.map +1 -1
- package/dist/sandbox/sandbox-config.js +2 -0
- package/dist/sandbox/sandbox-config.js.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts +1 -1
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.js +25 -7
- package/dist/sandbox/sandbox-manager.js.map +1 -1
- package/dist/sandbox/sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/sandbox-utils.js +20 -1
- package/dist/sandbox/sandbox-utils.js.map +1 -1
- package/dist/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/dist/vendor/seccomp/x64/apply-seccomp +0 -0
- package/dist/vendor/seccomp-src/apply-seccomp.c +98 -0
- package/package.json +1 -1
- package/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/vendor/seccomp/x64/apply-seccomp +0 -0
- package/vendor/seccomp-src/apply-seccomp.c +98 -0
- package/dist/vendor/seccomp-src/apply-seccomp-and-exec.py +0 -111
- package/vendor/seccomp-src/apply-seccomp-and-exec.py +0 -111
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Apply seccomp filter and exec command
|
|
4
|
-
|
|
5
|
-
This helper script loads a compiled seccomp BPF filter, applies it to the
|
|
6
|
-
current process using prctl, and then execs the specified command. This enables
|
|
7
|
-
two-stage seccomp application: infrastructure code runs without the filter,
|
|
8
|
-
then the user command runs with the filter active.
|
|
9
|
-
|
|
10
|
-
Usage:
|
|
11
|
-
./apply-seccomp-and-exec.py <filter-file> -- <command> [args...]
|
|
12
|
-
|
|
13
|
-
The filter file should contain a compiled BPF program (struct sock_fprog).
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
import sys
|
|
17
|
-
import os
|
|
18
|
-
import ctypes
|
|
19
|
-
import ctypes.util
|
|
20
|
-
|
|
21
|
-
# Constants
|
|
22
|
-
PR_SET_NO_NEW_PRIVS = 38
|
|
23
|
-
PR_SET_SECCOMP = 22
|
|
24
|
-
SECCOMP_MODE_FILTER = 2
|
|
25
|
-
|
|
26
|
-
# Define sock_filter structure (8 bytes)
|
|
27
|
-
class sock_filter(ctypes.Structure):
|
|
28
|
-
_fields_ = [
|
|
29
|
-
("code", ctypes.c_uint16),
|
|
30
|
-
("jt", ctypes.c_uint8),
|
|
31
|
-
("jf", ctypes.c_uint8),
|
|
32
|
-
("k", ctypes.c_uint32),
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
# Define sock_fprog structure
|
|
36
|
-
class sock_fprog(ctypes.Structure):
|
|
37
|
-
_fields_ = [
|
|
38
|
-
("len", ctypes.c_uint16),
|
|
39
|
-
("filter", ctypes.POINTER(sock_filter)),
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
def load_filter(path):
|
|
43
|
-
"""Load BPF filter from file"""
|
|
44
|
-
try:
|
|
45
|
-
with open(path, 'rb') as f:
|
|
46
|
-
data = f.read()
|
|
47
|
-
except IOError as e:
|
|
48
|
-
print(f"Error: Failed to open filter file {path}: {e}", file=sys.stderr)
|
|
49
|
-
sys.exit(1)
|
|
50
|
-
|
|
51
|
-
# Verify size is valid
|
|
52
|
-
filter_size = ctypes.sizeof(sock_filter)
|
|
53
|
-
if len(data) == 0 or len(data) % filter_size != 0:
|
|
54
|
-
print(f"Error: Invalid filter file size: {len(data)}", file=sys.stderr)
|
|
55
|
-
sys.exit(1)
|
|
56
|
-
|
|
57
|
-
# Parse filter data into array
|
|
58
|
-
num_filters = len(data) // filter_size
|
|
59
|
-
filter_array = (sock_filter * num_filters)()
|
|
60
|
-
ctypes.memmove(filter_array, data, len(data))
|
|
61
|
-
|
|
62
|
-
# Create fprog structure
|
|
63
|
-
prog = sock_fprog()
|
|
64
|
-
prog.len = num_filters
|
|
65
|
-
prog.filter = ctypes.cast(filter_array, ctypes.POINTER(sock_filter))
|
|
66
|
-
|
|
67
|
-
return prog, filter_array # Keep array alive
|
|
68
|
-
|
|
69
|
-
def main():
|
|
70
|
-
if len(sys.argv) < 4:
|
|
71
|
-
print(f"Usage: {sys.argv[0]} <filter-file> -- <command> [args...]", file=sys.stderr)
|
|
72
|
-
print("\nApplies seccomp filter and execs the command", file=sys.stderr)
|
|
73
|
-
sys.exit(1)
|
|
74
|
-
|
|
75
|
-
# Check for separator
|
|
76
|
-
if sys.argv[2] != '--':
|
|
77
|
-
print("Error: Expected '--' as second argument", file=sys.stderr)
|
|
78
|
-
sys.exit(1)
|
|
79
|
-
|
|
80
|
-
filter_path = sys.argv[1]
|
|
81
|
-
command_argv = sys.argv[3:]
|
|
82
|
-
|
|
83
|
-
# Load the BPF filter
|
|
84
|
-
prog, filter_array = load_filter(filter_path)
|
|
85
|
-
|
|
86
|
-
# Load libc
|
|
87
|
-
libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
|
|
88
|
-
|
|
89
|
-
# Set no_new_privs (required for unprivileged processes)
|
|
90
|
-
ret = libc.prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)
|
|
91
|
-
if ret < 0:
|
|
92
|
-
errno = ctypes.get_errno()
|
|
93
|
-
print(f"Error: Failed to set no_new_privs: {os.strerror(errno)}", file=sys.stderr)
|
|
94
|
-
sys.exit(1)
|
|
95
|
-
|
|
96
|
-
# Apply the seccomp filter
|
|
97
|
-
ret = libc.prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ctypes.byref(prog), 0, 0)
|
|
98
|
-
if ret < 0:
|
|
99
|
-
errno = ctypes.get_errno()
|
|
100
|
-
print(f"Error: Failed to apply seccomp filter: {os.strerror(errno)}", file=sys.stderr)
|
|
101
|
-
sys.exit(1)
|
|
102
|
-
|
|
103
|
-
# Filter is now active - exec the command
|
|
104
|
-
try:
|
|
105
|
-
os.execvp(command_argv[0], command_argv)
|
|
106
|
-
except OSError as e:
|
|
107
|
-
print(f"Error: Failed to exec {command_argv[0]}: {e}", file=sys.stderr)
|
|
108
|
-
sys.exit(1)
|
|
109
|
-
|
|
110
|
-
if __name__ == '__main__':
|
|
111
|
-
main()
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Apply seccomp filter and exec command
|
|
4
|
-
|
|
5
|
-
This helper script loads a compiled seccomp BPF filter, applies it to the
|
|
6
|
-
current process using prctl, and then execs the specified command. This enables
|
|
7
|
-
two-stage seccomp application: infrastructure code runs without the filter,
|
|
8
|
-
then the user command runs with the filter active.
|
|
9
|
-
|
|
10
|
-
Usage:
|
|
11
|
-
./apply-seccomp-and-exec.py <filter-file> -- <command> [args...]
|
|
12
|
-
|
|
13
|
-
The filter file should contain a compiled BPF program (struct sock_fprog).
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
import sys
|
|
17
|
-
import os
|
|
18
|
-
import ctypes
|
|
19
|
-
import ctypes.util
|
|
20
|
-
|
|
21
|
-
# Constants
|
|
22
|
-
PR_SET_NO_NEW_PRIVS = 38
|
|
23
|
-
PR_SET_SECCOMP = 22
|
|
24
|
-
SECCOMP_MODE_FILTER = 2
|
|
25
|
-
|
|
26
|
-
# Define sock_filter structure (8 bytes)
|
|
27
|
-
class sock_filter(ctypes.Structure):
|
|
28
|
-
_fields_ = [
|
|
29
|
-
("code", ctypes.c_uint16),
|
|
30
|
-
("jt", ctypes.c_uint8),
|
|
31
|
-
("jf", ctypes.c_uint8),
|
|
32
|
-
("k", ctypes.c_uint32),
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
# Define sock_fprog structure
|
|
36
|
-
class sock_fprog(ctypes.Structure):
|
|
37
|
-
_fields_ = [
|
|
38
|
-
("len", ctypes.c_uint16),
|
|
39
|
-
("filter", ctypes.POINTER(sock_filter)),
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
def load_filter(path):
|
|
43
|
-
"""Load BPF filter from file"""
|
|
44
|
-
try:
|
|
45
|
-
with open(path, 'rb') as f:
|
|
46
|
-
data = f.read()
|
|
47
|
-
except IOError as e:
|
|
48
|
-
print(f"Error: Failed to open filter file {path}: {e}", file=sys.stderr)
|
|
49
|
-
sys.exit(1)
|
|
50
|
-
|
|
51
|
-
# Verify size is valid
|
|
52
|
-
filter_size = ctypes.sizeof(sock_filter)
|
|
53
|
-
if len(data) == 0 or len(data) % filter_size != 0:
|
|
54
|
-
print(f"Error: Invalid filter file size: {len(data)}", file=sys.stderr)
|
|
55
|
-
sys.exit(1)
|
|
56
|
-
|
|
57
|
-
# Parse filter data into array
|
|
58
|
-
num_filters = len(data) // filter_size
|
|
59
|
-
filter_array = (sock_filter * num_filters)()
|
|
60
|
-
ctypes.memmove(filter_array, data, len(data))
|
|
61
|
-
|
|
62
|
-
# Create fprog structure
|
|
63
|
-
prog = sock_fprog()
|
|
64
|
-
prog.len = num_filters
|
|
65
|
-
prog.filter = ctypes.cast(filter_array, ctypes.POINTER(sock_filter))
|
|
66
|
-
|
|
67
|
-
return prog, filter_array # Keep array alive
|
|
68
|
-
|
|
69
|
-
def main():
|
|
70
|
-
if len(sys.argv) < 4:
|
|
71
|
-
print(f"Usage: {sys.argv[0]} <filter-file> -- <command> [args...]", file=sys.stderr)
|
|
72
|
-
print("\nApplies seccomp filter and execs the command", file=sys.stderr)
|
|
73
|
-
sys.exit(1)
|
|
74
|
-
|
|
75
|
-
# Check for separator
|
|
76
|
-
if sys.argv[2] != '--':
|
|
77
|
-
print("Error: Expected '--' as second argument", file=sys.stderr)
|
|
78
|
-
sys.exit(1)
|
|
79
|
-
|
|
80
|
-
filter_path = sys.argv[1]
|
|
81
|
-
command_argv = sys.argv[3:]
|
|
82
|
-
|
|
83
|
-
# Load the BPF filter
|
|
84
|
-
prog, filter_array = load_filter(filter_path)
|
|
85
|
-
|
|
86
|
-
# Load libc
|
|
87
|
-
libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
|
|
88
|
-
|
|
89
|
-
# Set no_new_privs (required for unprivileged processes)
|
|
90
|
-
ret = libc.prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)
|
|
91
|
-
if ret < 0:
|
|
92
|
-
errno = ctypes.get_errno()
|
|
93
|
-
print(f"Error: Failed to set no_new_privs: {os.strerror(errno)}", file=sys.stderr)
|
|
94
|
-
sys.exit(1)
|
|
95
|
-
|
|
96
|
-
# Apply the seccomp filter
|
|
97
|
-
ret = libc.prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ctypes.byref(prog), 0, 0)
|
|
98
|
-
if ret < 0:
|
|
99
|
-
errno = ctypes.get_errno()
|
|
100
|
-
print(f"Error: Failed to apply seccomp filter: {os.strerror(errno)}", file=sys.stderr)
|
|
101
|
-
sys.exit(1)
|
|
102
|
-
|
|
103
|
-
# Filter is now active - exec the command
|
|
104
|
-
try:
|
|
105
|
-
os.execvp(command_argv[0], command_argv)
|
|
106
|
-
except OSError as e:
|
|
107
|
-
print(f"Error: Failed to exec {command_argv[0]}: {e}", file=sys.stderr)
|
|
108
|
-
sys.exit(1)
|
|
109
|
-
|
|
110
|
-
if __name__ == '__main__':
|
|
111
|
-
main()
|