Social cloud hosting
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add seccomp profile for container syscall filtering

Embeds a restrictive seccomp profile that allows only necessary
syscalls for JavaScript runtimes. Blocks dangerous operations like
ptrace, mount, kernel module loading, and most privilege escalation
vectors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+311 -5
+17 -5
internal/vm/container.go
··· 2 2 3 3 import ( 4 4 "bytes" 5 + _ "embed" 5 6 "encoding/json" 6 7 "fmt" 7 8 "os" ··· 11 12 "time" 12 13 ) 13 14 15 + //go:embed seccomp/runtime.json 16 + var seccompProfile []byte 17 + 14 18 // ContainerPool runs bundles in OCI containers (Docker/Podman) 15 19 // Provides namespace isolation + seccomp without requiring KVM 16 20 type ContainerPool struct { 17 - runtime string // "docker" or "podman" 18 - runtimesDir string 19 - runtimes map[string]ContainerRuntime 21 + runtime string // "docker" or "podman" 22 + runtimesDir string 23 + runtimes map[string]ContainerRuntime 24 + seccompPath string // path to seccomp profile file 20 25 } 21 26 22 27 type ContainerRuntime struct { ··· 72 77 return nil, err 73 78 } 74 79 80 + // Write seccomp profile to temp file 81 + seccompPath := filepath.Join(os.TempDir(), "at-rund-seccomp.json") 82 + if err := os.WriteFile(seccompPath, seccompProfile, 0644); err != nil { 83 + return nil, fmt.Errorf("failed to write seccomp profile: %w", err) 84 + } 85 + 75 86 return &ContainerPool{ 76 87 runtime: runtime, 77 88 runtimesDir: runtimesDir, 78 89 runtimes: DefaultContainerRuntimes(), 90 + seccompPath: seccompPath, 79 91 }, nil 80 92 } 81 93 ··· 222 234 // Set the working directory 223 235 args = append(args, "-w", "/bundle") 224 236 225 - // Seccomp profile (use default for now, can customize later) 226 - // args = append(args, "--security-opt", "seccomp=/path/to/profile.json") 237 + // Apply seccomp profile for syscall filtering 238 + args = append(args, "--security-opt", fmt.Sprintf("seccomp=%s", p.seccompPath)) 227 239 228 240 // The image and command 229 241 args = append(args, runtime.Image)
+294
internal/vm/seccomp/runtime.json
··· 1 + { 2 + "defaultAction": "SCMP_ACT_ERRNO", 3 + "defaultErrnoRet": 1, 4 + "architectures": [ 5 + "SCMP_ARCH_X86_64", 6 + "SCMP_ARCH_X86", 7 + "SCMP_ARCH_AARCH64" 8 + ], 9 + "syscalls": [ 10 + { 11 + "names": [ 12 + "accept", 13 + "accept4", 14 + "access", 15 + "arch_prctl", 16 + "bind", 17 + "brk", 18 + "capget", 19 + "capset", 20 + "chdir", 21 + "chmod", 22 + "clock_getres", 23 + "clock_gettime", 24 + "clock_nanosleep", 25 + "clone", 26 + "clone3", 27 + "close", 28 + "close_range", 29 + "connect", 30 + "copy_file_range", 31 + "dup", 32 + "dup2", 33 + "dup3", 34 + "epoll_create", 35 + "epoll_create1", 36 + "epoll_ctl", 37 + "epoll_pwait", 38 + "epoll_pwait2", 39 + "epoll_wait", 40 + "eventfd", 41 + "eventfd2", 42 + "execve", 43 + "execveat", 44 + "exit", 45 + "exit_group", 46 + "faccessat", 47 + "faccessat2", 48 + "fadvise64", 49 + "fallocate", 50 + "fchdir", 51 + "fchmod", 52 + "fchmodat", 53 + "fchown", 54 + "fchownat", 55 + "fcntl", 56 + "fdatasync", 57 + "fgetxattr", 58 + "flistxattr", 59 + "flock", 60 + "fstat", 61 + "fstatfs", 62 + "fsync", 63 + "ftruncate", 64 + "futex", 65 + "futex_waitv", 66 + "getcwd", 67 + "getdents", 68 + "getdents64", 69 + "getegid", 70 + "geteuid", 71 + "getgid", 72 + "getgroups", 73 + "getpeername", 74 + "getpgid", 75 + "getpgrp", 76 + "getpid", 77 + "getppid", 78 + "getpriority", 79 + "getrandom", 80 + "getresgid", 81 + "getresuid", 82 + "getrlimit", 83 + "getrusage", 84 + "getsid", 85 + "getsockname", 86 + "getsockopt", 87 + "gettid", 88 + "gettimeofday", 89 + "getuid", 90 + "getxattr", 91 + "inotify_add_watch", 92 + "inotify_init", 93 + "inotify_init1", 94 + "inotify_rm_watch", 95 + "ioctl", 96 + "io_uring_enter", 97 + "io_uring_register", 98 + "io_uring_setup", 99 + "kill", 100 + "landlock_add_rule", 101 + "landlock_create_ruleset", 102 + "landlock_restrict_self", 103 + "lgetxattr", 104 + "link", 105 + "linkat", 106 + "listen", 107 + "listxattr", 108 + "llistxattr", 109 + "lseek", 110 + "lstat", 111 + "madvise", 112 + "membarrier", 113 + "memfd_create", 114 + "mincore", 115 + "mkdir", 116 + "mkdirat", 117 + "mlock", 118 + "mlock2", 119 + "mlockall", 120 + "mmap", 121 + "mprotect", 122 + "mremap", 123 + "msync", 124 + "munlock", 125 + "munlockall", 126 + "munmap", 127 + "nanosleep", 128 + "newfstatat", 129 + "open", 130 + "openat", 131 + "openat2", 132 + "pause", 133 + "pipe", 134 + "pipe2", 135 + "poll", 136 + "ppoll", 137 + "prctl", 138 + "pread64", 139 + "preadv", 140 + "preadv2", 141 + "prlimit64", 142 + "pselect6", 143 + "pwrite64", 144 + "pwritev", 145 + "pwritev2", 146 + "read", 147 + "readahead", 148 + "readlink", 149 + "readlinkat", 150 + "readv", 151 + "recv", 152 + "recvfrom", 153 + "recvmmsg", 154 + "recvmsg", 155 + "rename", 156 + "renameat", 157 + "renameat2", 158 + "restart_syscall", 159 + "rmdir", 160 + "rseq", 161 + "rt_sigaction", 162 + "rt_sigpending", 163 + "rt_sigprocmask", 164 + "rt_sigqueueinfo", 165 + "rt_sigreturn", 166 + "rt_sigsuspend", 167 + "rt_sigtimedwait", 168 + "rt_tgsigqueueinfo", 169 + "sched_getaffinity", 170 + "sched_getattr", 171 + "sched_getparam", 172 + "sched_get_priority_max", 173 + "sched_get_priority_min", 174 + "sched_getscheduler", 175 + "sched_rr_get_interval", 176 + "sched_setaffinity", 177 + "sched_setattr", 178 + "sched_setparam", 179 + "sched_setscheduler", 180 + "sched_yield", 181 + "seccomp", 182 + "select", 183 + "semctl", 184 + "semget", 185 + "semop", 186 + "semtimedop", 187 + "send", 188 + "sendfile", 189 + "sendmmsg", 190 + "sendmsg", 191 + "sendto", 192 + "set_robust_list", 193 + "set_tid_address", 194 + "setfsgid", 195 + "setfsuid", 196 + "setgid", 197 + "setgroups", 198 + "setitimer", 199 + "setpgid", 200 + "setpriority", 201 + "setregid", 202 + "setresgid", 203 + "setresuid", 204 + "setreuid", 205 + "setsid", 206 + "setsockopt", 207 + "setuid", 208 + "shmat", 209 + "shmctl", 210 + "shmdt", 211 + "shmget", 212 + "shutdown", 213 + "sigaltstack", 214 + "signalfd", 215 + "signalfd4", 216 + "socket", 217 + "socketpair", 218 + "splice", 219 + "stat", 220 + "statfs", 221 + "statx", 222 + "symlink", 223 + "symlinkat", 224 + "sync", 225 + "sync_file_range", 226 + "syncfs", 227 + "sysinfo", 228 + "tee", 229 + "tgkill", 230 + "time", 231 + "timer_create", 232 + "timer_delete", 233 + "timer_getoverrun", 234 + "timer_gettime", 235 + "timer_settime", 236 + "timerfd_create", 237 + "timerfd_gettime", 238 + "timerfd_settime", 239 + "times", 240 + "tkill", 241 + "truncate", 242 + "ugetrlimit", 243 + "umask", 244 + "uname", 245 + "unlink", 246 + "unlinkat", 247 + "utimensat", 248 + "utimes", 249 + "vfork", 250 + "wait4", 251 + "waitid", 252 + "waitpid", 253 + "write", 254 + "writev" 255 + ], 256 + "action": "SCMP_ACT_ALLOW" 257 + }, 258 + { 259 + "names": ["personality"], 260 + "action": "SCMP_ACT_ALLOW", 261 + "args": [ 262 + {"index": 0, "value": 0, "op": "SCMP_CMP_EQ"} 263 + ] 264 + }, 265 + { 266 + "names": ["personality"], 267 + "action": "SCMP_ACT_ALLOW", 268 + "args": [ 269 + {"index": 0, "value": 8, "op": "SCMP_CMP_EQ"} 270 + ] 271 + }, 272 + { 273 + "names": ["personality"], 274 + "action": "SCMP_ACT_ALLOW", 275 + "args": [ 276 + {"index": 0, "value": 131072, "op": "SCMP_CMP_EQ"} 277 + ] 278 + }, 279 + { 280 + "names": ["personality"], 281 + "action": "SCMP_ACT_ALLOW", 282 + "args": [ 283 + {"index": 0, "value": 131080, "op": "SCMP_CMP_EQ"} 284 + ] 285 + }, 286 + { 287 + "names": ["personality"], 288 + "action": "SCMP_ACT_ALLOW", 289 + "args": [ 290 + {"index": 0, "value": 4294967295, "op": "SCMP_CMP_EQ"} 291 + ] 292 + } 293 + ] 294 + }