diff options
| author | Paul Eggert | 2025-06-27 23:53:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2025-06-27 23:54:45 -0700 |
| commit | dd1efa5309d82139c6637e21ebd9eeb55e1814c1 (patch) | |
| tree | 441168d59e70a7ec07832143032caa327e46ecd4 /lib-src/seccomp-filter.c | |
| parent | dbdf761187d7cccfad20a2899bab3dc77f379c3a (diff) | |
| download | emacs-dd1efa5309d82139c6637e21ebd9eeb55e1814c1.tar.gz emacs-dd1efa5309d82139c6637e21ebd9eeb55e1814c1.zip | |
Port varargs macros better to C99
C99 prohibits passing zero args to macro’s ‘...’.
* lib-src/seccomp-filter.c (RULE0): New macro, which is like RULE
except with zero args. All zero-arg uses of RULE changed to RULE0.
* src/comp.c (compile_function, Fcomp__init_ctxt, syms_of_comp):
Change ‘CALLN (Fmake_hash_table)’ to ‘Fmake_hash_table (0, NULL)’,
since CALLN requires at least two args in C99.
Diffstat (limited to 'lib-src/seccomp-filter.c')
| -rw-r--r-- | lib-src/seccomp-filter.c | 119 |
1 files changed, 64 insertions, 55 deletions
diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c index e9f41afbaba..07fd35998c9 100644 --- a/lib-src/seccomp-filter.c +++ b/lib-src/seccomp-filter.c | |||
| @@ -127,6 +127,15 @@ set_attribute (enum scmp_filter_attr attr, uint32_t value) | |||
| 127 | #action, #syscall, arg_cnt, #__VA_ARGS__); \ | 127 | #action, #syscall, arg_cnt, #__VA_ARGS__); \ |
| 128 | } \ | 128 | } \ |
| 129 | while (false) | 129 | while (false) |
| 130 | #define RULE0(action, syscall) \ | ||
| 131 | do \ | ||
| 132 | { \ | ||
| 133 | int status = seccomp_rule_add (ctx, action, syscall, 0); \ | ||
| 134 | if (status < 0) \ | ||
| 135 | fail (-status, "seccomp_rule_add (%s, %s, 0)", \ | ||
| 136 | #action, #syscall); \ | ||
| 137 | } \ | ||
| 138 | while (false) | ||
| 130 | 139 | ||
| 131 | static void | 140 | static void |
| 132 | export_filter (const char *file, | 141 | export_filter (const char *file, |
| @@ -178,8 +187,8 @@ main (int argc, char **argv) | |||
| 178 | assert ((uintptr_t) NULL == 0); | 187 | assert ((uintptr_t) NULL == 0); |
| 179 | 188 | ||
| 180 | /* Allow a clean exit. */ | 189 | /* Allow a clean exit. */ |
| 181 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit)); | 190 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (exit)); |
| 182 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (exit_group)); | 191 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (exit_group)); |
| 183 | 192 | ||
| 184 | /* Allow `mmap' and friends. This is necessary for dynamic loading, | 193 | /* Allow `mmap' and friends. This is necessary for dynamic loading, |
| 185 | reading the portable dump file, and thread creation. We don't | 194 | reading the portable dump file, and thread creation. We don't |
| @@ -206,58 +215,58 @@ main (int argc, char **argv) | |||
| 206 | ~(MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | 215 | ~(MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED |
| 207 | | MAP_DENYWRITE), | 216 | | MAP_DENYWRITE), |
| 208 | 0)); | 217 | 0)); |
| 209 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (munmap)); | 218 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (munmap)); |
| 210 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (mprotect), | 219 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (mprotect), |
| 211 | /* Don't allow making pages executable. */ | 220 | /* Don't allow making pages executable. */ |
| 212 | SCMP_A2_32 (SCMP_CMP_MASKED_EQ, | 221 | SCMP_A2_32 (SCMP_CMP_MASKED_EQ, |
| 213 | ~(PROT_NONE | PROT_READ | PROT_WRITE), 0)); | 222 | ~(PROT_NONE | PROT_READ | PROT_WRITE), 0)); |
| 214 | 223 | ||
| 215 | /* Allow restartable sequences. The dynamic linker uses them. */ | 224 | /* Allow restartable sequences. The dynamic linker uses them. */ |
| 216 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (rseq)); | 225 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (rseq)); |
| 217 | 226 | ||
| 218 | /* Futexes are used everywhere. */ | 227 | /* Futexes are used everywhere. */ |
| 219 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex), | 228 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex), |
| 220 | SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE)); | 229 | SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE)); |
| 221 | 230 | ||
| 222 | /* Allow basic dynamic memory management. */ | 231 | /* Allow basic dynamic memory management. */ |
| 223 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (brk)); | 232 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (brk)); |
| 224 | 233 | ||
| 225 | /* Allow some status inquiries. */ | 234 | /* Allow some status inquiries. */ |
| 226 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (uname)); | 235 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (uname)); |
| 227 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getuid)); | 236 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getuid)); |
| 228 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (geteuid)); | 237 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (geteuid)); |
| 229 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpid)); | 238 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getpid)); |
| 230 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (gettid)); | 239 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (gettid)); |
| 231 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp)); | 240 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp)); |
| 232 | 241 | ||
| 233 | /* Allow operations on open file descriptors. File descriptors are | 242 | /* Allow operations on open file descriptors. File descriptors are |
| 234 | capabilities, and operating on them shouldn't cause security | 243 | capabilities, and operating on them shouldn't cause security |
| 235 | issues. */ | 244 | issues. */ |
| 236 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (read)); | 245 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (read)); |
| 237 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (pread64)); | 246 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (pread64)); |
| 238 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (write)); | 247 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (write)); |
| 239 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (close)); | 248 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (close)); |
| 240 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (lseek)); | 249 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (lseek)); |
| 241 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup)); | 250 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (dup)); |
| 242 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (dup2)); | 251 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (dup2)); |
| 243 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstat)); | 252 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (fstat)); |
| 244 | 253 | ||
| 245 | /* Allow read operations on the filesystem. If necessary, these | 254 | /* Allow read operations on the filesystem. If necessary, these |
| 246 | should be further restricted using mount namespaces. */ | 255 | should be further restricted using mount namespaces. */ |
| 247 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (access)); | 256 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (access)); |
| 248 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat)); | 257 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (faccessat)); |
| 249 | #ifdef __NR_faccessat2 | 258 | #ifdef __NR_faccessat2 |
| 250 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (faccessat2)); | 259 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (faccessat2)); |
| 251 | #endif | 260 | #endif |
| 252 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat)); | 261 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (stat)); |
| 253 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (stat64)); | 262 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (stat64)); |
| 254 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat)); | 263 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (lstat)); |
| 255 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (lstat64)); | 264 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (lstat64)); |
| 256 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (fstatat64)); | 265 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (fstatat64)); |
| 257 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (newfstatat)); | 266 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (newfstatat)); |
| 258 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlink)); | 267 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (readlink)); |
| 259 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (readlinkat)); | 268 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (readlinkat)); |
| 260 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getcwd)); | 269 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getcwd)); |
| 261 | 270 | ||
| 262 | /* Allow opening files, assuming they are only opened for | 271 | /* Allow opening files, assuming they are only opened for |
| 263 | reading. */ | 272 | reading. */ |
| @@ -292,17 +301,17 @@ main (int argc, char **argv) | |||
| 292 | SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); | 301 | SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); |
| 293 | 302 | ||
| 294 | /* Allow reading random numbers from the kernel. */ | 303 | /* Allow reading random numbers from the kernel. */ |
| 295 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrandom)); | 304 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getrandom)); |
| 296 | 305 | ||
| 297 | /* Changing the umask is uncritical. */ | 306 | /* Changing the umask is uncritical. */ |
| 298 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (umask)); | 307 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (umask)); |
| 299 | 308 | ||
| 300 | /* Allow creation of pipes. */ | 309 | /* Allow creation of pipes. */ |
| 301 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe)); | 310 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (pipe)); |
| 302 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (pipe2)); | 311 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (pipe2)); |
| 303 | 312 | ||
| 304 | /* Allow reading (but not changing) resource limits. */ | 313 | /* Allow reading (but not changing) resource limits. */ |
| 305 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (getrlimit)); | 314 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (getrlimit)); |
| 306 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (prlimit64), | 315 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (prlimit64), |
| 307 | SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */, | 316 | SCMP_A0_32 (SCMP_CMP_EQ, 0) /* pid == 0 (current process) */, |
| 308 | SCMP_A2_64 (SCMP_CMP_EQ, 0) /* new_limit == NULL */); | 317 | SCMP_A2_64 (SCMP_CMP_EQ, 0) /* new_limit == NULL */); |
| @@ -313,20 +322,20 @@ main (int argc, char **argv) | |||
| 313 | SCMP_A2_64 (SCMP_CMP_NE, 0) /* new_limit != NULL */); | 322 | SCMP_A2_64 (SCMP_CMP_NE, 0) /* new_limit != NULL */); |
| 314 | 323 | ||
| 315 | /* Emacs installs signal handlers, which is harmless. */ | 324 | /* Emacs installs signal handlers, which is harmless. */ |
| 316 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaction)); | 325 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (sigaction)); |
| 317 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigaction)); | 326 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigaction)); |
| 318 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigprocmask)); | 327 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (sigprocmask)); |
| 319 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigprocmask)); | 328 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (rt_sigprocmask)); |
| 320 | 329 | ||
| 321 | /* Allow reading the current time. */ | 330 | /* Allow reading the current time. */ |
| 322 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (clock_gettime), | 331 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (clock_gettime), |
| 323 | SCMP_A0_32 (SCMP_CMP_EQ, CLOCK_REALTIME)); | 332 | SCMP_A0_32 (SCMP_CMP_EQ, CLOCK_REALTIME)); |
| 324 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (time)); | 333 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (time)); |
| 325 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (gettimeofday)); | 334 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (gettimeofday)); |
| 326 | 335 | ||
| 327 | /* Allow timer support. */ | 336 | /* Allow timer support. */ |
| 328 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (timer_create)); | 337 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (timer_create)); |
| 329 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (timerfd_create)); | 338 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (timerfd_create)); |
| 330 | 339 | ||
| 331 | /* Allow thread creation. See the NOTES section in the manual page | 340 | /* Allow thread creation. See the NOTES section in the manual page |
| 332 | for the `clone' function. */ | 341 | for the `clone' function. */ |
| @@ -340,25 +349,25 @@ main (int argc, char **argv) | |||
| 340 | | CLONE_CHILD_CLEARTID), | 349 | | CLONE_CHILD_CLEARTID), |
| 341 | 0)); | 350 | 0)); |
| 342 | /* glibc 2.34+ pthread_create uses clone3. */ | 351 | /* glibc 2.34+ pthread_create uses clone3. */ |
| 343 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone3)); | 352 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (clone3)); |
| 344 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack)); | 353 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack)); |
| 345 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list)); | 354 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list)); |
| 346 | 355 | ||
| 347 | /* Allow setting the process name for new threads. */ | 356 | /* Allow setting the process name for new threads. */ |
| 348 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl), | 357 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (prctl), |
| 349 | SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NAME)); | 358 | SCMP_A0_32 (SCMP_CMP_EQ, PR_SET_NAME)); |
| 350 | 359 | ||
| 351 | /* Allow some event handling functions used by glib. */ | 360 | /* Allow some event handling functions used by glib. */ |
| 352 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd)); | 361 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (eventfd)); |
| 353 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2)); | 362 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (eventfd2)); |
| 354 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (wait4)); | 363 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (wait4)); |
| 355 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (poll)); | 364 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (poll)); |
| 356 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (pidfd_open), | 365 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (pidfd_open), |
| 357 | SCMP_A1_32 (SCMP_CMP_EQ, 0)); | 366 | SCMP_A1_32 (SCMP_CMP_EQ, 0)); |
| 358 | 367 | ||
| 359 | /* Don't allow creating sockets (network access would be extremely | 368 | /* Don't allow creating sockets (network access would be extremely |
| 360 | dangerous), but also don't crash. */ | 369 | dangerous), but also don't crash. */ |
| 361 | RULE (SCMP_ACT_ERRNO (EACCES), SCMP_SYS (socket)); | 370 | RULE0 (SCMP_ACT_ERRNO (EACCES), SCMP_SYS (socket)); |
| 362 | 371 | ||
| 363 | EXPORT_FILTER (argv[1], seccomp_export_bpf); | 372 | EXPORT_FILTER (argv[1], seccomp_export_bpf); |
| 364 | EXPORT_FILTER (argv[2], seccomp_export_pfc); | 373 | EXPORT_FILTER (argv[2], seccomp_export_pfc); |
| @@ -368,15 +377,15 @@ main (int argc, char **argv) | |||
| 368 | calls. Firstly, the wrapper binary will need to `execve' the | 377 | calls. Firstly, the wrapper binary will need to `execve' the |
| 369 | Emacs binary. Furthermore, the C library requires some system | 378 | Emacs binary. Furthermore, the C library requires some system |
| 370 | calls at startup time to set up thread-local storage. */ | 379 | calls at startup time to set up thread-local storage. */ |
| 371 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (execve)); | 380 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (execve)); |
| 372 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_tid_address)); | 381 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (set_tid_address)); |
| 373 | RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (prctl), | 382 | RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (prctl), |
| 374 | SCMP_A0_32 (SCMP_CMP_EQ, PR_CAPBSET_READ)); | 383 | SCMP_A0_32 (SCMP_CMP_EQ, PR_CAPBSET_READ)); |
| 375 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (arch_prctl), | 384 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (arch_prctl), |
| 376 | SCMP_A0_32 (SCMP_CMP_EQ, ARCH_SET_FS)); | 385 | SCMP_A0_32 (SCMP_CMP_EQ, ARCH_SET_FS)); |
| 377 | RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (arch_prctl), | 386 | RULE (SCMP_ACT_ERRNO (EINVAL), SCMP_SYS (arch_prctl), |
| 378 | SCMP_A0_32 (SCMP_CMP_EQ, ARCH_CET_STATUS)); | 387 | SCMP_A0_32 (SCMP_CMP_EQ, ARCH_CET_STATUS)); |
| 379 | RULE (SCMP_ACT_ALLOW, SCMP_SYS (statfs)); | 388 | RULE0 (SCMP_ACT_ALLOW, SCMP_SYS (statfs)); |
| 380 | 389 | ||
| 381 | /* We want to allow starting the Emacs binary itself with the | 390 | /* We want to allow starting the Emacs binary itself with the |
| 382 | --seccomp flag, so we need to allow the `prctl' and `seccomp' | 391 | --seccomp flag, so we need to allow the `prctl' and `seccomp' |