v0.7.1: allow network inside the run_shell sandbox

Landlock no longer handles TCP, the Seatbelt profile drops (deny network*),
and the seccomp filter stops refusing IPv4/IPv6 sockets. Sandboxed commands
run without asking in auto mode on every backend (Low-IL no longer asks for
network commands), and connection errors are not treated as sandbox blocks.
This commit is contained in:
WHC
2026-10-08 21:05:14 +08:00
parent 895b47274c
commit 32b4afd772
8 changed files with 36 additions and 62 deletions
+5 -19
View File
@@ -86,8 +86,6 @@ static int g_abi;
#define LL_FS_MAKE_SYM (1ULL << 12)
#define LL_FS_REFER (1ULL << 13) /* ABI 2 */
#define LL_FS_TRUNCATE (1ULL << 14) /* ABI 3 */
#define LL_NET_BIND_TCP (1ULL << 0) /* ABI 4 */
#define LL_NET_CONNECT_TCP (1ULL << 1) /* ABI 4 */
struct ll_ruleset_attr {
uint64_t handled_access_fs;
@@ -137,9 +135,7 @@ static int ll_prepare(const char *ws, const char *tmp, cst_sandbox_plan_t *p) {
int abi = g_abi;
struct ll_ruleset_attr attr;
memset(&attr, 0, sizeof(attr));
attr.handled_access_fs = ll_write_rights(abi);
if (abi >= 4)
attr.handled_access_net = LL_NET_BIND_TCP | LL_NET_CONNECT_TCP;
attr.handled_access_fs = ll_write_rights(abi); /* network stays open */
int fd = (int)syscall(__NR_landlock_create_ruleset, &attr, sizeof(attr), 0);
if (fd < 0)
return -1;
@@ -193,8 +189,7 @@ static int sb_prepare(const char *ws, const char *tmp, cst_sandbox_plan_t *p) {
"(version 1)(allow default)(deny file-write*)"
"(allow file-write* (subpath \"%s\") (subpath \"%s\") "
"(literal \"/dev/null\") (literal \"/dev/tty\") "
"(literal \"/dev/dtracehelper\"))"
"(deny network*)",
"(literal \"/dev/dtracehelper\"))",
qws, qtmp);
return 0;
}
@@ -290,9 +285,8 @@ static const int SC_NOTIFY[] = {
#endif
};
/* Foreign ABIs are refused, IPv4/IPv6 sockets fail with EACCES, opens
* without write flags pass untouched, write-type calls go to the
* supervisor. */
/* Foreign ABIs are refused, opens without write flags pass untouched,
* write-type calls go to the supervisor. */
static void sc_build(sc_prog_t *p) {
p->n = 0;
SC_LD(offsetof(struct seccomp_data, arch));
@@ -303,12 +297,6 @@ static void sc_build(sc_prog_t *p) {
sc_emit(p, BPF_JMP | BPF_JGE | BPF_K, 0, 1, 0x40000000U); /* x32 */
SC_RET(SECCOMP_RET_ERRNO | EPERM);
#endif
SC_JEQ(__NR_socket, 0, 5);
SC_LD(SC_ARG(0));
SC_JEQ(AF_INET, 2, 0);
SC_JEQ(AF_INET6, 1, 0);
SC_RET(SECCOMP_RET_ALLOW);
SC_RET(SECCOMP_RET_ERRNO | EACCES);
SC_JEQ(__NR_io_uring_setup, 0, 1);
SC_RET(SECCOMP_RET_ERRNO | EPERM);
SC_JEQ(__NR_openat, 0, 4);
@@ -1446,9 +1434,7 @@ int cst_sandbox_blocked(const char *out, size_t n, int exit_code) {
static const char *const SIGNS[] = {
"Permission denied", "Read-only file system", "Operation not permitted",
"EACCES", "EPERM", "EROFS",
"[cst: sandbox", "Network is unreachable",
/* curl when the socket itself was refused (seccomp) */
"Could not connect to server", "Failed to connect to",
"[cst: sandbox",
/* localized strerror(EACCES/EPERM/EROFS) */
"权限不够", "不允许的操作", "只读文件系统", "權限不足",
"拒絕不符權限的操作", "許可がありません", "Keine Berechtigung",