1 module symmetry.linux.seccomp; 2 version(Posix): 3 4 import symmetry.sildoc; 5 6 import std.conv : to; 7 8 extern(C) nothrow @nogc: 9 10 /** 11 * Seccomp Library 12 * 13 * Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com> 14 * Author: Paul Moore <paul@paul-moore.com> 15 */ 16 17 /* 18 * This library is free software; you can redistribute it and/or modify it 19 * under the terms of version 2.1 of the GNU Lesser General Public License as 20 * published by the Free Software Foundation. 21 * 22 * This library is distributed in the hope that it will be useful, but WITHOUT 23 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 25 * for more details. 26 * 27 * You should have received a copy of the GNU Lesser General Public License 28 * along with this library; if not, see <http://www.gnu.org/licenses>. 29 */ 30 31 32 // #include <elf.h> 33 // #include <inttypes.h> 34 // #include <asm/unistd.h> 35 // #include <linux/audit.h> 36 37 38 /* 39 * version information 40 */ 41 42 enum SCMP_VER_MAJOR = 2; 43 enum SCMP_VER_MINOR = 4; 44 enum SCMP_VER_MICRO = 1; 45 46 struct scmp_version 47 { 48 uint major; 49 uint minor; 50 uint micro; 51 } 52 53 /* 54 * types 55 */ 56 57 /** 58 * Filter context/handle 59 */ 60 alias scmp_filter_ctx = void*; 61 alias scmp_filter_ctx_const = const(void)*; 62 63 /** 64 * Filter attributes 65 */ 66 enum FilterAttribute 67 { 68 min = 0, 69 70 @SILdoc("default filter action") 71 defaultAction = 1, 72 73 @SILdoc("bad architecture action") 74 badArchitectureAction = 2, 75 76 @SILdoc("set NO_NEW_PRIVS on filter load") 77 controlNoNewPrivileges = 3, 78 79 @SILdoc("sync threads on filter load") 80 controlSyncThreads = 4, 81 82 @SILdoc("allow rules with a -1 syscall") 83 apiTskip = 5, 84 85 @SILdoc("log not-allowed actions") 86 controlLog = 6, 87 _SCMP_FLTATR_MAX, 88 } 89 90 /** 91 * Comparison operators 92 */ 93 enum SecCompCompare 94 { 95 min = 0, 96 notEqual = 1, /**< not equal */ 97 lessThan = 2, /**< less than */ 98 lessThanEqual = 3, /**< less than or equal */ 99 equal = 4, /**< equal */ 100 greaterThanEqual = 5, /**< greater than or equal */ 101 greaterThan = 6, /**< greater than */ 102 maskedEquality = 7, /**< masked equality */ 103 max, 104 } 105 106 /** 107 * Argument datum 108 */ 109 alias scmp_datum_t= ulong; 110 111 /** 112 * Argument / Value comparison definition 113 */ 114 struct SecCompArgCmp 115 { 116 uint arg; /**< argument number, starting at 0 */ 117 SecCompCompare op; /**< the comparison op, e.g. SCMP_CMP_* */ 118 scmp_datum_t datum_a; 119 scmp_datum_t datum_b; 120 } 121 122 /* 123 * macros/defines 124 */ 125 126 /** 127 * The native architecture token 128 */ 129 enum SCMP_ARCH_NATIVE = 0; 130 131 /** 132 * The x86 (32-bit) architecture token 133 */ 134 // enum SCMP_ARCH_X86 = AUDIT_ARCH_I386; 135 136 /** 137 * The x86-64 (64-bit) architecture token 138 */ 139 //enum SCMP_ARCH_X86_64 = AUDIT_ARCH_X86_64; 140 141 /** 142 * The x32 (32-bit x86_64) architecture token 143 * 144 * NOTE: this is different from the value used by the kernel because we need to 145 * be able to distinguish between x32 and x86_64 146 */ 147 //enum SCMP_ARCH_X32 = (EM_X86_64|__AUDIT_ARCH_LE); 148 149 /** 150 * The ARM architecture tokens 151 */ 152 //enum SCMP_ARCH_ARM = AUDIT_ARCH_ARM; 153 /* AArch64 support for audit was merged in 3.17-rc1 */ 154 155 /+ 156 #ifndef AUDIT_ARCH_AARCH64 157 #ifndef EM_AARCH64 158 enum EM_AARCH64 183 159 #endif /* EM_AARCH64 */ 160 enum AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) 161 #endif /* AUDIT_ARCH_AARCH64 */ 162 +/ 163 //enum SCMP_ARCH_AARCH64 = AUDIT_ARCH_AARCH64; 164 165 /+ 166 /** 167 * The MIPS architecture tokens 168 */ 169 #ifndef __AUDIT_ARCH_CONVENTION_MIPS64_N32 170 enum __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000 171 #endif 172 #ifndef EM_MIPS 173 enum EM_MIPS 8 174 #endif 175 #ifndef AUDIT_ARCH_MIPS 176 enum AUDIT_ARCH_MIPS (EM_MIPS) 177 #endif 178 #ifndef AUDIT_ARCH_MIPS64 179 enum AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT) 180 #endif 181 +/ 182 183 184 /+ 185 /* MIPS64N32 support was merged in 3.15 */ 186 #ifndef AUDIT_ARCH_MIPS64N32 187 enum AUDIT_ARCH_MIPS64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|\ 188 __AUDIT_ARCH_CONVENTION_MIPS64_N32) 189 #endif 190 +/ 191 192 /+ 193 /* MIPSEL64N32 support was merged in 3.15 */ 194 #ifndef AUDIT_ARCH_MIPSEL64N32 195 enum AUDIT_ARCH_MIPSEL64N32 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE|\ 196 __AUDIT_ARCH_CONVENTION_MIPS64_N32) 197 #endif 198 +/ 199 200 /+ 201 enum SCMP_ARCH_MIPS AUDIT_ARCH_MIPS 202 enum SCMP_ARCH_MIPS64 AUDIT_ARCH_MIPS64 203 enum SCMP_ARCH_MIPS64N32 AUDIT_ARCH_MIPS64N32 204 enum SCMP_ARCH_MIPSEL AUDIT_ARCH_MIPSEL 205 enum SCMP_ARCH_MIPSEL64 AUDIT_ARCH_MIPSEL64 206 enum SCMP_ARCH_MIPSEL64N32 AUDIT_ARCH_MIPSEL64N32 207 208 /** 209 * The PowerPC architecture tokens 210 */ 211 enum SCMP_ARCH_PPC AUDIT_ARCH_PPC 212 enum SCMP_ARCH_PPC64 AUDIT_ARCH_PPC64 213 #ifndef AUDIT_ARCH_PPC64LE 214 enum AUDIT_ARCH_PPC64LE (EM_PPC64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) 215 #endif 216 enum SCMP_ARCH_PPC64LE AUDIT_ARCH_PPC64LE 217 218 /** 219 * The S390 architecture tokens 220 */ 221 enum SCMP_ARCH_S390 AUDIT_ARCH_S390 222 enum SCMP_ARCH_S390X AUDIT_ARCH_S390X 223 224 /** 225 * The PA-RISC hppa architecture tokens 226 */ 227 enum SCMP_ARCH_PARISC AUDIT_ARCH_PARISC 228 enum SCMP_ARCH_PARISC64 AUDIT_ARCH_PARISC64 229 +/ 230 /+ 231 /** 232 * Convert a syscall name into the associated syscall number 233 * @param x the syscall name 234 */ 235 enum SCMP_SYS(x) (__NR_##x) 236 237 /* Helpers for the argument comparison macros, DO NOT USE directly */ 238 enum _SCMP_VA_NUM_ARGS(...) _SCMP_VA_NUM_ARGS_IMPL(__VA_ARGS__,2,1) 239 enum _SCMP_VA_NUM_ARGS_IMPL(_1,_2,N,...) N 240 enum _SCMP_MACRO_DISPATCHER(func, ...) \ 241 _SCMP_MACRO_DISPATCHER_IMPL1(func, _SCMP_VA_NUM_ARGS(__VA_ARGS__)) 242 enum _SCMP_MACRO_DISPATCHER_IMPL1(func, nargs) \ 243 _SCMP_MACRO_DISPATCHER_IMPL2(func, nargs) 244 enum _SCMP_MACRO_DISPATCHER_IMPL2(func, nargs) \ 245 func ## nargs 246 enum _SCMP_CMP32_1(x, y, z) \ 247 SCMP_CMP64(x, y, (uint)(z)) 248 enum _SCMP_CMP32_2(x, y, z, q) \ 249 SCMP_CMP64(x, y, (uint)(z), (uint)(q)) 250 +/ 251 /** 252 * Specify a 64-bit argument comparison struct for use in declaring rules 253 * @param arg the argument number, starting at 0 254 * @param op the comparison operator, e.g. SCMP_CMP_* 255 * @param datum_a dependent on comparison 256 * @param datum_b dependent on comparison, optional 257 */ 258 auto SCMP_CMP64(T...)(T args) 259 { 260 return SecCompArgCmp(args); 261 } 262 263 // enum SCMP_CMP64(...) ((struct SecCompArgCmp){__VA_ARGS__}) 264 alias SCMP_CMP = SCMP_CMP64; 265 266 /+ 267 /** 268 * Specify a 32-bit argument comparison struct for use in declaring rules 269 * @param arg the argument number, starting at 0 270 * @param op the comparison operator, e.g. SCMP_CMP_* 271 * @param datum_a dependent on comparison (32-bits) 272 * @param datum_b dependent on comparison, optional (32-bits) 273 */ 274 //enum SCMP_CMP32(x, y, ...) \ 275 // _SCMP_MACRO_DISPATCHER(_SCMP_CMP32_, __VA_ARGS__)(x, y, __VA_ARGS__) 276 auto SCMP_CMP32(T...)(uint x, uint y, T args) 277 { 278 return _SCMP_MACRO_DISPATCHER(_SCMP_CMP32_, __VA_ARGS__)(x, y, __VA_ARGS__) 279 280 /** 281 * Specify a 64-bit argument comparison struct for argument 0 282 */ 283 enum SCMP_A0_64(...) SCMP_CMP64(0, __VA_ARGS__) 284 enum SCMP_A0 SCMP_A0_64 285 286 /** 287 * Specify a 32-bit argument comparison struct for argument 0 288 */ 289 enum SCMP_A0_32(x, ...) SCMP_CMP32(0, x, __VA_ARGS__) 290 291 /** 292 * Specify a 64-bit argument comparison struct for argument 1 293 */ 294 enum SCMP_A1_64(...) SCMP_CMP64(1, __VA_ARGS__) 295 enum SCMP_A1 SCMP_A1_64 296 297 /** 298 * Specify a 32-bit argument comparison struct for argument 1 299 */ 300 enum SCMP_A1_32(x, ...) SCMP_CMP32(1, x, __VA_ARGS__) 301 302 /** 303 * Specify a 64-bit argument comparison struct for argument 2 304 */ 305 enum SCMP_A2_64(...) SCMP_CMP64(2, __VA_ARGS__) 306 enum SCMP_A2 SCMP_A2_64 307 308 /** 309 * Specify a 32-bit argument comparison struct for argument 2 310 */ 311 enum SCMP_A2_32(x, ...) SCMP_CMP32(2, x, __VA_ARGS__) 312 313 /** 314 * Specify a 64-bit argument comparison struct for argument 3 315 */ 316 enum SCMP_A3_64(...) SCMP_CMP64(3, __VA_ARGS__) 317 enum SCMP_A3 SCMP_A3_64 318 319 /** 320 * Specify a 32-bit argument comparison struct for argument 3 321 */ 322 enum SCMP_A3_32(x, ...) SCMP_CMP32(3, x, __VA_ARGS__) 323 324 /** 325 * Specify a 64-bit argument comparison struct for argument 4 326 */ 327 enum SCMP_A4_64(...) SCMP_CMP64(4, __VA_ARGS__) 328 enum SCMP_A4 SCMP_A4_64 329 330 /** 331 * Specify a 32-bit argument comparison struct for argument 4 332 */ 333 enum SCMP_A4_32(x, ...) SCMP_CMP32(4, x, __VA_ARGS__) 334 335 /** 336 * Specify a 64-bit argument comparison struct for argument 5 337 */ 338 enum SCMP_A5_64(...) SCMP_CMP64(5, __VA_ARGS__) 339 enum SCMP_A5 SCMP_A5_64 340 341 /** 342 * Specify a 32-bit argument comparison struct for argument 5 343 */ 344 enum SCMP_A5_32(x, ...) SCMP_CMP32(5, x, __VA_ARGS__) 345 +/ 346 /* 347 * seccomp actions 348 */ 349 350 /** 351 * Kill the process 352 */ 353 enum SCMP_ACT_KILL_PROCESS = "80000000".to!uint(16); 354 /** 355 * Kill the thread 356 */ 357 enum SCMP_ACT_KILL_THREAD = "00000000".to!uint(16); 358 /** 359 * Kill the thread, defined for backward compatibility 360 */ 361 enum SCMP_ACT_KILL = SCMP_ACT_KILL_THREAD; 362 /** 363 * Throw a SIGSYS signal 364 */ 365 enum SCMP_ACT_TRAP = "00030000".to!uint(16); 366 /** 367 * Return the specified error code 368 */ 369 auto SCMP_ACT_ERRNO(uint x) 370 { 371 enum exp1 = "00050000".to!uint(16); 372 enum exp2= "0000ffff".to!uint(16); 373 return exp1 | (x & exp2); 374 } 375 376 /** 377 * Notify a tracing process with the specified value 378 */ 379 auto SCMP_ACT_TRACE(uint x) 380 { 381 enum exp1 = "7ff00000".to!uint(16); 382 enum exp2 = "0000ffff".to!uint(16); 383 return exp1 | (x & exp2); 384 } 385 386 /** 387 * Allow the syscall to be executed after the action has been logged 388 */ 389 enum SCMP_ACT_LOG ="7ffc0000".to!uint(16); 390 /** 391 * Allow the syscall to be executed 392 */ 393 enum SCMP_ACT_ALLOW = "7fff0000".to!uint(16); 394 395 enum SecCompAction 396 { 397 @SILdoc("Kill the process") 398 killProcess = SCMP_ACT_KILL_PROCESS, 399 400 @SILdoc("Kill the thread") 401 killThread = SCMP_ACT_KILL_THREAD, 402 403 @SILdoc("Kill the thread, defined for backward compatibility") 404 kill = SCMP_ACT_KILL_THREAD, 405 406 @SILdoc("Throw a SIGSYS signal") 407 trap = SCMP_ACT_TRAP, 408 409 @SILdoc("Allow ths syscall to be executed after the action has been logged") 410 log = SCMP_ACT_LOG, 411 412 @SILdoc("Allow the syscall to be executed") 413 allow = SCMP_ACT_ALLOW, 414 } 415 416 alias secCompActionReturnErrno = SCMP_ACT_ERRNO; 417 alias secCompActionTrace = SCMP_ACT_TRACE; 418 419 auto secCompActionFail() 420 { 421 import core.stdc.errno : EPERM; 422 return secCompActionReturnErrno(EPERM); 423 } 424 425 /* 426 * functions 427 */ 428 429 @SILdoc(" 430 Query the library version information: 431 - This function returns a pointer to a populated scmp_version struct, the 432 - caller does not need to free the structure when finished.") 433 const(scmp_version)* seccomp_version(); 434 435 @SILdoc(" 436 Query the library's level of API support 437 This function returns an API level value indicating the current supported 438 functionality. It is important to note that this level of support is 439 determined at runtime and therefore can change based on the running kernel 440 and system configuration (e.g. any previously loaded seccomp filters). This 441 function can be called multiple times, but it only queries the system the 442 first time it is called, the API level is cached and used in subsequent calls. 443 444 The current API levels are described below: 445 0 : reserved 446 1 : base level 447 2 : support for the SCMP_FLTATR_CTL_TSYNC filter attribute 448 uses the seccomp(2) syscall instead of the prctl(2) syscall 449 3 : support for the SCMP_FLTATR_CTL_LOG filter attribute 450 support for the SCMP_ACT_LOG action 451 support for the SCMP_ACT_KILL_PROCESS action 452 ") 453 uint seccomp_api_get(); 454 455 @SILdoc(" 456 Set the library's level of API support 457 This function forcibly sets the API level of the library at runtime. Valid 458 API levels are discussed in the description of the seccomp_api_get() 459 function. General use of this function is strongly discouraged.") 460 int seccomp_api_set(uint level); 461 462 @SILdoc(" 463 Initialize the filter state 464 @param def_action the default filter action 465 This function initializes the internal seccomp filter state and should 466 be called before any other functions in this library to ensure the filter 467 state is initialized. Returns a filter context on success, NULL on failure. 468 ") 469 scmp_filter_ctx seccomp_init(uint def_action); 470 471 /** 472 * Reset the filter state 473 * @param ctx the filter context 474 * @param def_action the default filter action 475 * 476 * This function resets the given seccomp filter state and ensures the 477 * filter state is reinitialized. This function does not reset any seccomp 478 * filters already loaded into the kernel. Returns zero on success, negative 479 * values on failure. 480 * 481 */ 482 int seccomp_reset(scmp_filter_ctx ctx, uint def_action); 483 484 /** 485 * Destroys the filter state and releases any resources 486 * @param ctx the filter context 487 * 488 * This functions destroys the given seccomp filter state and releases any 489 * resources, including memory, associated with the filter state. This 490 * function does not reset any seccomp filters already loaded into the kernel. 491 * The filter context can no longer be used after calling this function. 492 * 493 */ 494 void seccomp_release(scmp_filter_ctx ctx); 495 496 /** 497 * Merge two filters 498 * @param ctx_dst the destination filter context 499 * @param ctx_src the source filter context 500 * 501 * This function merges two filter contexts into a single filter context and 502 * destroys the second filter context. The two filter contexts must have the 503 * same attribute values and not contain any of the same architectures; if they 504 * do, the merge operation will fail. On success, the source filter context 505 * will be destroyed and should no longer be used; it is not necessary to 506 * call seccomp_release() on the source filter context. Returns zero on 507 * success, negative values on failure. 508 * 509 */ 510 int seccomp_merge(scmp_filter_ctx ctx_dst, scmp_filter_ctx ctx_src); 511 512 /** 513 * Resolve the architecture name to a architecture token 514 * @param arch_name the architecture name 515 * 516 * This function resolves the given architecture name to a token suitable for 517 * use with libseccomp, returns zero on failure. 518 * 519 */ 520 uint seccomp_arch_resolve_name(const(char) *arch_name); 521 522 /** 523 * Return the native architecture token 524 * 525 * This function returns the native architecture token value, e.g. SCMP_ARCH_*. 526 * 527 */ 528 uint seccomp_arch_native(); 529 530 /** 531 * Check to see if an existing architecture is present in the filter 532 * @param ctx the filter context 533 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 534 * 535 * This function tests to see if a given architecture is included in the filter 536 * context. If the architecture token is SCMP_ARCH_NATIVE then the native 537 * architecture will be assumed. Returns zero if the architecture exists in 538 * the filter, -EEXIST if it is not present, and other negative values on 539 * failure. 540 * 541 */ 542 int seccomp_arch_exist(scmp_filter_ctx_const ctx, uint arch_token); 543 544 /** 545 * Adds an architecture to the filter 546 * @param ctx the filter context 547 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 548 * 549 * This function adds a new architecture to the given seccomp filter context. 550 * Any new rules added after this function successfully returns will be added 551 * to this architecture but existing rules will not be added to this 552 * architecture. If the architecture token is SCMP_ARCH_NATIVE then the native 553 * architecture will be assumed. Returns zero on success, -EEXIST if 554 * specified architecture is already present, other negative values on failure. 555 * 556 */ 557 int seccomp_arch_add(scmp_filter_ctx ctx, uint arch_token); 558 559 /** 560 * Removes an architecture from the filter 561 * @param ctx the filter context 562 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 563 * 564 * This function removes an architecture from the given seccomp filter context. 565 * If the architecture token is SCMP_ARCH_NATIVE then the native architecture 566 * will be assumed. Returns zero on success, negative values on failure. 567 * 568 */ 569 int seccomp_arch_remove(scmp_filter_ctx ctx, uint arch_token); 570 571 /** 572 * Loads the filter into the kernel 573 * @param ctx the filter context 574 * 575 * This function loads the given seccomp filter context into the kernel. If 576 * the filter was loaded correctly, the kernel will be enforcing the filter 577 * when this function returns. Returns zero on success, negative values on 578 * error. 579 * 580 */ 581 int seccomp_load(scmp_filter_ctx_const ctx); 582 583 /** 584 * Get the value of a filter attribute 585 * @param ctx the filter context 586 * @param attr the filter attribute name 587 * @param value the filter attribute value 588 * 589 * This function fetches the value of the given attribute name and returns it 590 * via @value. Returns zero on success, negative values on failure. 591 * 592 */ 593 int seccomp_attr_get(scmp_filter_ctx_const ctx, FilterAttribute attr, uint *value); 594 595 /** 596 * Set the value of a filter attribute 597 * @param ctx the filter context 598 * @param attr the filter attribute name 599 * @param value the filter attribute value 600 * 601 * This function sets the value of the given attribute. Returns zero on 602 * success, negative values on failure. 603 * 604 */ 605 int seccomp_attr_set(scmp_filter_ctx ctx, FilterAttribute attr, uint value); 606 607 /** 608 * Resolve a syscall number to a name 609 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 610 * @param num the syscall number 611 * 612 * Resolve the given syscall number to the syscall name for the given 613 * architecture; it is up to the caller to free the returned string. Returns 614 * the syscall name on success, NULL on failure. 615 * 616 */ 617 char *seccomp_syscall_resolve_num_arch(uint arch_token, int num); 618 619 /** 620 * Resolve a syscall name to a number 621 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 622 * @param name the syscall name 623 * 624 * Resolve the given syscall name to the syscall number for the given 625 * architecture. Returns the syscall number on success, including negative 626 * pseudo syscall numbers (e.g. PseudoSyscall.*); returns __NR_SCMP_ERROR on failure. 627 * 628 */ 629 int seccomp_syscall_resolve_name_arch(uint arch_token, const(char) *name); 630 631 /** 632 * Resolve a syscall name to a number and perform any rewriting necessary 633 * @param arch_token the architecture token, e.g. SCMP_ARCH_* 634 * @param name the syscall name 635 * 636 * Resolve the given syscall name to the syscall number for the given 637 * architecture and do any necessary syscall rewriting needed by the 638 * architecture. Returns the syscall number on success, including negative 639 * pseudo syscall numbers (e.g. PseudoSyscall.*); returns __NR_SCMP_ERROR on failure. 640 * 641 */ 642 int seccomp_syscall_resolve_name_rewrite(uint arch_token, const(char) *name); 643 644 /** 645 * Resolve a syscall name to a number 646 * @param name the syscall name 647 * 648 * Resolve the given syscall name to the syscall number. Returns the syscall 649 * number on success, including negative pseudo syscall numbers (e.g. PseudoSyscall.*); 650 * returns __NR_SCMP_ERROR on failure. 651 * 652 */ 653 int seccomp_syscall_resolve_name(const(char) *name); 654 655 /** 656 * Set the priority of a given syscall 657 * @param ctx the filter context 658 * @param syscall the syscall number 659 * @param priority priority value, higher value == higher priority 660 * 661 * This function sets the priority of the given syscall; this value is used 662 * when generating the seccomp filter code such that higher priority syscalls 663 * will incur less filter code overhead than the lower priority syscalls in the 664 * filter. Returns zero on success, negative values on failure. 665 * 666 */ 667 int seccomp_syscall_priority(scmp_filter_ctx ctx, 668 int syscall, ubyte priority); 669 670 /** 671 * Add a new rule to the filter 672 * @param ctx the filter context 673 * @param action the filter action 674 * @param syscall the syscall number 675 * @param arg_cnt the number of argument filters in the argument filter chain 676 * @param ... SecCompArgCmp structs (use of SCMP_ARG_CMP() recommended) 677 * 678 * This function adds a series of new argument/value checks to the seccomp 679 * filter for the given syscall; multiple argument/value checks can be 680 * specified and they will be chained together (AND'd together) in the filter. 681 * If the specified rule needs to be adjusted due to architecture specifics it 682 * will be adjusted without notification. Returns zero on success, negative 683 * values on failure. 684 * 685 */ 686 int seccomp_rule_add(scmp_filter_ctx ctx, 687 uint action, int syscall, uint arg_cnt, ...); 688 689 690 /** 691 * Add a new rule to the filter 692 * @param ctx the filter context 693 * @param action the filter action 694 * @param syscall the syscall number 695 * @param arg_cnt the number of elements in the arg_array parameter 696 * @param arg_array array of SecCompArgCmp structs 697 * 698 * This function adds a series of new argument/value checks to the seccomp 699 * filter for the given syscall; multiple argument/value checks can be 700 * specified and they will be chained together (AND'd together) in the filter. 701 * If the specified rule needs to be adjusted due to architecture specifics it 702 * will be adjusted without notification. Returns zero on success, negative 703 * values on failure. 704 * 705 */ 706 int seccomp_rule_add_array(scmp_filter_ctx ctx, 707 uint action, int syscall, uint arg_cnt, 708 const(SecCompArgCmp)* arg_array); 709 710 /** 711 * Add a new rule to the filter 712 * @param ctx the filter context 713 * @param action the filter action 714 * @param syscall the syscall number 715 * @param arg_cnt the number of argument filters in the argument filter chain 716 * @param ... SecCompArgCmp structs (use of SCMP_ARG_CMP() recommended) 717 * 718 * This function adds a series of new argument/value checks to the seccomp 719 * filter for the given syscall; multiple argument/value checks can be 720 * specified and they will be chained together (AND'd together) in the filter. 721 * If the specified rule can not be represented on the architecture the 722 * function will fail. Returns zero on success, negative values on failure. 723 * 724 */ 725 int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint action, 726 int syscall, uint arg_cnt, ...); 727 728 /** 729 * Add a new rule to the filter 730 * @param ctx the filter context 731 * @param action the filter action 732 * @param syscall the syscall number 733 * @param arg_cnt the number of elements in the arg_array parameter 734 * @param arg_array array of SecCompArgCmp structs 735 * 736 * This function adds a series of new argument/value checks to the seccomp 737 * filter for the given syscall; multiple argument/value checks can be 738 * specified and they will be chained together (AND'd together) in the filter. 739 * If the specified rule can not be represented on the architecture the 740 * function will fail. Returns zero on success, negative values on failure. 741 * 742 */ 743 int seccomp_rule_add_exact_array(scmp_filter_ctx ctx, 744 uint action, int syscall, 745 uint arg_cnt, 746 const(SecCompArgCmp)* arg_array); 747 748 /** 749 * Generate seccomp Pseudo Filter Code (PFC) and export it to a file 750 * @param ctx the filter context 751 * @param fd the destination fd 752 * 753 * This function generates seccomp Pseudo Filter Code (PFC) and writes it to 754 * the given fd. Returns zero on success, negative values on failure. 755 * 756 */ 757 int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd); 758 759 /** 760 * Generate seccomp Berkley Packet Filter (BPF) code and export it to a file 761 * @param ctx the filter context 762 * @param fd the destination fd 763 * 764 * This function generates seccomp Berkley Packer Filter (BPF) code and writes 765 * it to the given fd. Returns zero on success, negative values on failure. 766 * 767 */ 768 int seccomp_export_bpf(scmp_filter_ctx ctx, int fd); 769 770 /// pseudo syscall definitions 771 enum PseudoSyscall 772 { 773 // NOTE - pseudo syscall values {-1..-99} are reserved 774 error = -1, 775 undef = -2, 776 777 socket = -101, 778 bind = -102, 779 connect = -103, 780 listen = -104, 781 accept = -105, 782 getsockname = -106, 783 getpeername = -107, 784 socketpair = -108, 785 send = -109, 786 recv = -110, 787 sendto = -111, 788 recvfrom = -112, 789 shutdown = -113, 790 setsockopt = -114, 791 getsockopt = -115, 792 sendmsg = -116, 793 recvmsg = -117, 794 accept4 = -118, 795 recvmmsg = -119, 796 sendmmsg = -120, 797 semop = -201, 798 semget = -202, 799 semctl = -203, 800 semtimedop = -204, 801 msgsnd = -211, 802 msgrcv = -212, 803 msgget = -213, 804 msgctl = -214, 805 shmat = -221, 806 shmdt = -222, 807 shmget = -223, 808 shmctl = -224, 809 arch_prctl = -10001, 810 bdflush = -10002, 811 break_ = -10003, 812 chown32 = -10004, 813 epoll_ctl_old = -10005, 814 epoll_wait_old = -10006, 815 fadvise64_64 = -10007, 816 fchown32 = -10008, 817 fcntl64 = -10009, 818 fstat64 = -10010, 819 fstatat64 = -10011, 820 fstatfs64 = -10012, 821 ftime = -10013, 822 ftruncate64 = -10014, 823 getegid32 = -10015, 824 geteuid32 = -10016, 825 getgid32 = -10017, 826 getgroups32 = -10018, 827 getresgid32 = -10019, 828 getresuid32 = -10020, 829 getuid32 = -10021, 830 gtty = -10022, 831 idle = -10023, 832 ipc = -10024, 833 lchown32 = -10025, 834 _llseek = -10026, 835 lock = -10027, 836 lstat64 = -10028, 837 mmap2 = -10029, 838 mpx = -10030, 839 newfstatat = -10031, 840 _newselect = -10032, 841 nice = -10033, 842 oldfstat = -10034, 843 oldlstat = -10035, 844 oldolduname = -10036, 845 oldstat = -10037, 846 olduname = -10038, 847 prof = -10039, 848 profil = -10040, 849 readdir = -10041, 850 security = -10042, 851 sendfile64 = -10043, 852 setfsgid32 = -10044, 853 setfsuid32 = -10045, 854 setgid32 = -10046, 855 setgroups32 = -10047, 856 setregid32 = -10048, 857 setresgid32 = -10049, 858 setresuid32 = -10050, 859 setreuid32 = -10051, 860 setuid32 = -10052, 861 sgetmask = -10053, 862 sigaction = -10054, 863 signal = -10055, 864 sigpending = -10056, 865 sigprocmask = -10057, 866 sigreturn = -10058, 867 sigsuspend = -10059, 868 socketcall = -10060, 869 ssetmask = -10061, 870 stat64 = -10062, 871 statfs64 = -10063, 872 stime = -10064, 873 stty = -10065, 874 truncate64 = -10066, 875 tuxcall = -10067, 876 ugetrlimit = -10068, 877 ulimit = -10069, 878 umount = -10070, 879 vm86 = -10071, 880 vm86old = -10072, 881 waitpid = -10073, 882 create_module = -10074, 883 get_kernel_syms = -10075, 884 get_thread_area = -10076, 885 nfsservctl = -10077, 886 query_module = -10078, 887 set_thread_area = -10079, 888 sysctl = -10080, 889 uselib = -10081, 890 vserver = -10082, 891 arm_fadvise64_64= -10083, 892 arm_sync_file_range = -10084, 893 pciconfig_iobase = -10086, 894 pciconfig_read = -10087, 895 pciconfig_write = -10088, 896 sync_file_range2 = -10089, 897 syscall = -10090, 898 afs_syscall = -10091, 899 fadvise64 = -10092, 900 getpmsg = -10093, 901 ioperm = -10094, 902 iopl = -10095, 903 migrate_pages = -10097, 904 modify_ldt = -10098, 905 putpmsg = -10099, 906 sync_file_range = -10100, 907 select = -10101, 908 vfork = -10102, 909 cachectl = -10103, 910 sysmips = -10106, 911 timerfd = -10107, 912 time = -10108, 913 getrandom = -10109, 914 memfd_create = -10110, 915 kexec_file_load = -10111, 916 sysfs = -10145, 917 oldwait4 = -10146, 918 access = -10147, 919 alarm = -10148, 920 chmod = -10149, 921 chown = -10150, 922 creat = -10151, 923 dup2 = -10152, 924 epoll_create = -10153, 925 epoll_wait = -10154, 926 eventfd = -10155, 927 fork = -10156, 928 futimesat = -10157, 929 getdents = -10158, 930 getpgrp = -10159, 931 inotify_init = -10160, 932 lchown = -10161, 933 link = -10162, 934 lstat = -10163, 935 mkdir = -10164, 936 mknod = -10165, 937 open = -10166, 938 pause = -10167, 939 pipe = -10168, 940 poll = -10169, 941 readlink = -10170, 942 rename = -10171, 943 rmdir = -10172, 944 signalfd = -10173, 945 stat = -10174, 946 symlink = -10175, 947 unlink = -10176, 948 ustat = -10177, 949 utime = -10178, 950 utimes = -10179, 951 getrlimit = -10180, 952 mmap = -10181, 953 breakpoint = -10182, 954 set_tls = -10183, 955 usr26 = -10184, 956 usr32 = -10185, 957 multiplexer = -10186, 958 rtas = -10187, 959 spu_create = -10188, 960 spu_run = -10189, 961 swapcontext = -10190, 962 sys_debug_setcontext = -10191, 963 switch_endian = -10191, 964 get_mempolicy = -10192, 965 move_pages = -10193, 966 mbind = -10194, 967 set_mempolicy = -10195, 968 s390_runtime_instr = -10196, 969 s390_pci_mmio_read = -10197, 970 s390_pci_mmio_write = -10198, 971 membarrier = -10199, 972 userfaultfd = -10200, 973 pkey_mprotect = -10201, 974 pkey_alloc = -10202, 975 pkey_free = -10203, 976 get_tls = -10204, 977 s390_guarded_storage = -10205, 978 s390_sthyi = -10206, 979 subpage_prot = -10207, 980 statx = -10208, 981 io_pgetevents = -10209, 982 rseq = -10210, 983 } 984 985 version(X86_64) 986 { 987 enum Syscall : int 988 { 989 _llseek = PseudoSyscall._llseek, 990 _newselect = PseudoSyscall._newselect, 991 _sysctl = 156, 992 accept = 43, 993 accept4 = 288, 994 access = 21, 995 acct = 163, 996 add_key = 248, 997 adjtimex = 159, 998 afs_syscall = 183, 999 alarm = 37, 1000 arm_fadvise64_64 = PseudoSyscall.arm_fadvise64_64, 1001 arm_sync_file_range = PseudoSyscall.arm_sync_file_range, 1002 arch_prctl = 158, 1003 bdflush = PseudoSyscall.bdflush, 1004 bind = 49, 1005 bpf = 321, 1006 break_ = PseudoSyscall.break_, 1007 breakpoint = PseudoSyscall.breakpoint, 1008 brk = 12, 1009 cachectl = PseudoSyscall.cachectl, 1010 //cacheflush = PseudoSyscall.cacheflush, 1011 capget = 125, 1012 capset = 126, 1013 chdir = 80, 1014 chmod = 90, 1015 chown = 92, 1016 chown32 = PseudoSyscall.chown32, 1017 chroot = 161, 1018 clock_adjtime = 305, 1019 clock_getres = 229, 1020 clock_gettime = 228, 1021 clock_nanosleep = 230, 1022 clock_settime = 227, 1023 clone = 56, 1024 close = 3, 1025 connect = 42, 1026 copy_file_range = 326, 1027 creat = 85, 1028 create_module = 174, 1029 delete_module = 176, 1030 dup = 32, 1031 dup2 = 33, 1032 dup3 = 292, 1033 epoll_create = 213, 1034 epoll_create1 = 291, 1035 epoll_ctl = 233, 1036 epoll_ctl_old = 214, 1037 epoll_pwait = 281, 1038 epoll_wait = 232, 1039 epoll_wait_old = 215, 1040 eventfd = 284, 1041 eventfd2 = 290, 1042 execve = 59, 1043 execveat = 322, 1044 exit = 60, 1045 exit_group = 231, 1046 faccessat = 269, 1047 fadvise64 = 221, 1048 fadvise64_64 = PseudoSyscall.fadvise64_64, 1049 fallocate = 285, 1050 fanotify_init = 300, 1051 fanotify_mark = 301, 1052 fchdir = 81, 1053 fchmod = 91, 1054 fchmodat = 268, 1055 fchown = 93, 1056 fchown32 = PseudoSyscall.fchown32, 1057 fchownat = 260, 1058 fcntl = 72, 1059 fcntl64 = PseudoSyscall.fcntl64, 1060 fdatasync = 75, 1061 fgetxattr = 193, 1062 finit_module = 313, 1063 flistxattr = 196, 1064 flock = 73, 1065 fork = 57, 1066 fremovexattr = 199, 1067 fsetxattr = 190, 1068 fstat = 5, 1069 fstat64 = PseudoSyscall.fstat64, 1070 fstatat64 = PseudoSyscall.fstatat64, 1071 fstatfs = 138, 1072 fstatfs64 = PseudoSyscall.fstatfs64, 1073 fsync = 74, 1074 ftime = PseudoSyscall.ftime, 1075 ftruncate = 77, 1076 ftruncate64 = PseudoSyscall.ftruncate64, 1077 futex = 202, 1078 futimesat = 261, 1079 get_kernel_syms = 177, 1080 get_mempolicy = 239, 1081 get_robust_list = 274, 1082 get_thread_area = 211, 1083 get_tls = PseudoSyscall.get_tls, 1084 getcpu = 309, 1085 getcwd = 79, 1086 getdents = 78, 1087 getdents64 = 217, 1088 getegid = 108, 1089 getegid32 = PseudoSyscall.getegid32, 1090 geteuid = 107, 1091 geteuid32 = PseudoSyscall.geteuid32, 1092 getgid = 104, 1093 getgid32 = PseudoSyscall.getgid32, 1094 getgroups = 115, 1095 getgroups32 = PseudoSyscall.getgroups32, 1096 getitimer = 36, 1097 getpeername = 52, 1098 getpgid = 121, 1099 getpgrp = 111, 1100 getpid = 39, 1101 getpmsg = 181, 1102 getppid = 110, 1103 getpriority = 140, 1104 getrandom = 318, 1105 getresgid = 120, 1106 getresgid32 = PseudoSyscall.getresgid32, 1107 getresuid = 118, 1108 getresuid32 = PseudoSyscall.getresuid32, 1109 getrlimit = 97, 1110 getrusage = 98, 1111 getsid = 124, 1112 getsockname = 51, 1113 getsockopt = 55, 1114 gettid = 186, 1115 gettimeofday = 96, 1116 getuid = 102, 1117 getuid32 = PseudoSyscall.getuid32, 1118 getxattr = 191, 1119 gtty = PseudoSyscall.gtty, 1120 idle = PseudoSyscall.idle, 1121 init_module = 175, 1122 inotify_add_watch = 254, 1123 inotify_init = 253, 1124 inotify_init1 = 294, 1125 inotify_rm_watch = 255, 1126 io_cancel = 210, 1127 io_destroy = 207, 1128 io_getevents = 208, 1129 io_pgetevents = 333, 1130 io_setup = 206, 1131 io_submit = 209, 1132 io_uring_setup = 425, 1133 io_uring_enter = 426, 1134 io_uring_register = 427, 1135 ioctl = 16, 1136 ioperm = 173, 1137 iopl = 172, 1138 ioprio_get = 252, 1139 ioprio_set = 251, 1140 ipc = PseudoSyscall.ipc, 1141 kcmp = 312, 1142 kexec_file_load = 320, 1143 kexec_load = 246, 1144 keyctl = 250, 1145 kill = 62, 1146 lchown = 94, 1147 lchown32 = PseudoSyscall.lchown32, 1148 lgetxattr = 192, 1149 link = 86, 1150 linkat = 265, 1151 listen = 50, 1152 listxattr = 194, 1153 llistxattr = 195, 1154 lock = PseudoSyscall.lock, 1155 lookup_dcookie = 212, 1156 lremovexattr = 198, 1157 lseek = 8, 1158 lsetxattr = 189, 1159 lstat = 6, 1160 lstat64 = PseudoSyscall.lstat64, 1161 madvise = 28, 1162 mbind = 237, 1163 membarrier = 324, 1164 memfd_create = 319, 1165 migrate_pages = 256, 1166 mincore = 27, 1167 mkdir = 83, 1168 mkdirat = 258, 1169 mknod = 133, 1170 mknodat = 259, 1171 mlock = 149, 1172 mlock2 = 325, 1173 mlockall = 151, 1174 mmap = 9, 1175 mmap2 = PseudoSyscall.mmap2, 1176 modify_ldt = 154, 1177 mount = 165, 1178 move_pages = 279, 1179 mprotect = 10, 1180 mpx = PseudoSyscall.mpx, 1181 mq_getsetattr = 245, 1182 mq_notify = 244, 1183 mq_open = 240, 1184 mq_timedreceive = 243, 1185 mq_timedsend = 242, 1186 mq_unlink = 241, 1187 mremap = 25, 1188 msgctl = 71, 1189 msgget = 68, 1190 msgrcv = 70, 1191 msgsnd = 69, 1192 msync = 26, 1193 multiplexer = PseudoSyscall.multiplexer, 1194 munlock = 150, 1195 munlockall = 152, 1196 munmap = 11, 1197 name_to_handle_at = 303, 1198 nanosleep = 35, 1199 newfstatat = 262, 1200 nfsservctl = 180, 1201 nice = PseudoSyscall.nice, 1202 oldfstat = PseudoSyscall.oldfstat, 1203 oldlstat = PseudoSyscall.oldlstat, 1204 oldolduname = PseudoSyscall.oldolduname, 1205 oldstat = PseudoSyscall.oldstat, 1206 olduname = PseudoSyscall.olduname, 1207 oldwait4 = PseudoSyscall.oldwait4, 1208 open = 2, 1209 open_by_handle_at = 304, 1210 openat = 257, 1211 pause = 34, 1212 pciconfig_iobase = PseudoSyscall.pciconfig_iobase, 1213 pciconfig_read = PseudoSyscall.pciconfig_read, 1214 pciconfig_write = PseudoSyscall.pciconfig_write, 1215 perf_event_open = 298, 1216 personality = 135, 1217 pipe = 22, 1218 pipe2 = 293, 1219 pivot_root = 155, 1220 pkey_alloc = 330, 1221 pkey_free = 331, 1222 pkey_mprotect = 329, 1223 poll = 7, 1224 ppoll = 271, 1225 prctl = 157, 1226 pread64 = 17, 1227 preadv = 295, 1228 preadv2 = 327, 1229 prlimit64 = 302, 1230 process_vm_readv = 310, 1231 process_vm_writev = 311, 1232 prof = PseudoSyscall.prof, 1233 profil = PseudoSyscall.profil, 1234 pselect6 = 270, 1235 ptrace = 101, 1236 putpmsg = 182, 1237 pwrite64 = 18, 1238 pwritev = 296, 1239 pwritev2 = 328, 1240 query_module = 178, 1241 quotactl = 179, 1242 read = 0, 1243 readahead = 187, 1244 readdir = PseudoSyscall.readdir, 1245 readlink = 89, 1246 readlinkat = 267, 1247 readv = 19, 1248 reboot = 169, 1249 recv = PseudoSyscall.recv, 1250 recvfrom = 45, 1251 recvmmsg = 299, 1252 recvmsg = 47, 1253 remap_file_pages = 216, 1254 removexattr = 197, 1255 rename = 82, 1256 renameat = 264, 1257 renameat2 = 316, 1258 request_key = 249, 1259 restart_syscall = 219, 1260 rmdir = 84, 1261 rseq = 334, 1262 rt_sigaction = 13, 1263 rt_sigpending = 127, 1264 rt_sigprocmask = 14, 1265 rt_sigqueueinfo = 129, 1266 rt_sigreturn = 15, 1267 rt_sigsuspend = 130, 1268 rt_sigtimedwait = 128, 1269 rt_tgsigqueueinfo = 297, 1270 rtas = PseudoSyscall.rtas, 1271 s390_guarded_storage = PseudoSyscall.s390_guarded_storage, 1272 s390_pci_mmio_read = PseudoSyscall.s390_pci_mmio_read, 1273 s390_pci_mmio_write = PseudoSyscall.s390_pci_mmio_write, 1274 s390_runtime_instr = PseudoSyscall.s390_runtime_instr, 1275 s390_sthyi = PseudoSyscall.s390_sthyi, 1276 sched_get_priority_max = 146, 1277 sched_get_priority_min = 147, 1278 sched_getaffinity = 204, 1279 sched_getattr = 315, 1280 sched_getparam = 143, 1281 sched_getscheduler = 145, 1282 sched_rr_get_interval = 148, 1283 sched_setaffinity = 203, 1284 sched_setattr = 314, 1285 sched_setparam = 142, 1286 sched_setscheduler = 144, 1287 sched_yield = 24, 1288 seccomp = 317, 1289 security = 185, 1290 select = 23, 1291 semctl = 66, 1292 semget = 64, 1293 semop = 65, 1294 semtimedop = 220, 1295 send = PseudoSyscall.send, 1296 sendfile = 40, 1297 sendfile64 = PseudoSyscall.sendfile64, 1298 sendmmsg = 307, 1299 sendmsg = 46, 1300 sendto = 44, 1301 set_mempolicy = 238, 1302 set_robust_list = 273, 1303 set_thread_area = 205, 1304 set_tid_address = 218, 1305 set_tls = PseudoSyscall.set_tls, 1306 setdomainname = 171, 1307 setfsgid = 123, 1308 setfsgid32 = PseudoSyscall.setfsgid32, 1309 setfsuid = 122, 1310 setfsuid32 = PseudoSyscall.setfsuid32, 1311 setgid = 106, 1312 setgid32 = PseudoSyscall.setgid32, 1313 setgroups = 116, 1314 setgroups32 = PseudoSyscall.setgroups32, 1315 sethostname = 170, 1316 setitimer = 38, 1317 setns = 308, 1318 setpgid = 109, 1319 setpriority = 141, 1320 setregid = 114, 1321 setregid32 = PseudoSyscall.setregid32, 1322 setresgid = 119, 1323 setresgid32 = PseudoSyscall.setresgid32, 1324 setresuid = 117, 1325 setresuid32 = PseudoSyscall.setresuid32, 1326 setreuid = 113, 1327 setreuid32 = PseudoSyscall.setreuid32, 1328 setrlimit = 160, 1329 setsid = 112, 1330 setsockopt = 54, 1331 settimeofday = 164, 1332 setuid = 105, 1333 setuid32 = PseudoSyscall.setuid32, 1334 setxattr = 188, 1335 sgetmask = PseudoSyscall.sgetmask, 1336 shmat = 30, 1337 shmctl = 31, 1338 shmdt = 67, 1339 shmget = 29, 1340 shutdown = 48, 1341 sigaction = PseudoSyscall.sigaction, 1342 sigaltstack = 131, 1343 signal = PseudoSyscall.signal, 1344 signalfd = 282, 1345 signalfd4 = 289, 1346 sigpending = PseudoSyscall.sigpending, 1347 sigprocmask = PseudoSyscall.sigprocmask, 1348 sigreturn = PseudoSyscall.sigreturn, 1349 sigsuspend = PseudoSyscall.sigsuspend, 1350 socket = 41, 1351 socketcall = PseudoSyscall.socketcall, 1352 socketpair = 53, 1353 splice = 275, 1354 spu_create = PseudoSyscall.spu_create, 1355 spu_run = PseudoSyscall.spu_run, 1356 ssetmask = PseudoSyscall.ssetmask, 1357 stat = 4, 1358 stat64 = PseudoSyscall.stat64, 1359 statfs = 137, 1360 statfs64 = PseudoSyscall.statfs64, 1361 statx = 332, 1362 stime = PseudoSyscall.stime, 1363 stty = PseudoSyscall.stty, 1364 subpage_prot = PseudoSyscall.subpage_prot, 1365 swapcontext = PseudoSyscall.swapcontext, 1366 swapoff = 168, 1367 swapon = 167, 1368 switch_endian = PseudoSyscall.switch_endian, 1369 symlink = 88, 1370 symlinkat = 266, 1371 sync = 162, 1372 sync_file_range = 277, 1373 sync_file_range2 = PseudoSyscall.sync_file_range2, 1374 syncfs = 306, 1375 syscall = PseudoSyscall.syscall, 1376 sys_debug_setcontext = PseudoSyscall.sys_debug_setcontext, 1377 sysfs = 139, 1378 sysinfo = 99, 1379 syslog = 103, 1380 sysmips = PseudoSyscall.sysmips, 1381 tee = 276, 1382 tgkill = 234, 1383 time = 201, 1384 timer_create = 222, 1385 timer_delete = 226, 1386 timer_getoverrun = 225, 1387 timer_gettime = 224, 1388 timer_settime = 223, 1389 timerfd = PseudoSyscall.timerfd, 1390 timerfd_create = 283, 1391 timerfd_gettime = 287, 1392 timerfd_settime = 286, 1393 times = 100, 1394 tkill = 200, 1395 truncate = 76, 1396 truncate64 = PseudoSyscall.truncate64, 1397 tuxcall = 184, 1398 ugetrlimit = PseudoSyscall.ugetrlimit, 1399 ulimit = PseudoSyscall.ulimit, 1400 umask = 95, 1401 umount = PseudoSyscall.umount, 1402 umount2 = 166, 1403 uname = 63, 1404 unlink = 87, 1405 unlinkat = 263, 1406 unshare = 272, 1407 uselib = 134, 1408 userfaultfd = 323, 1409 usr26 = PseudoSyscall.usr26, 1410 usr32 = PseudoSyscall.usr32, 1411 ustat = 136, 1412 utime = 132, 1413 utimensat = 280, 1414 utimes = 235, 1415 vfork = 58, 1416 vhangup = 153, 1417 vm86 = PseudoSyscall.vm86, 1418 vm86old = PseudoSyscall.vm86old, 1419 vmsplice = 278, 1420 vserver = 236, 1421 wait4 = 61, 1422 waitid = 247, 1423 waitpid = PseudoSyscall.waitpid, 1424 write = 1, 1425 writev = 20, 1426 } 1427 } 1428 enum MAX_ERRNO = 4095; 1429 1430 /+ 1431 enum SECCOMP_MODE_DISABLED = 0; 1432 enum SECCOMP_MODE_STRICT = 1; 1433 enum SECCOMP_MODE_FILTER = 2; 1434 +/ 1435 /* 1436 * All BPF programs must return a 32-bit value. 1437 * The bottom 16-bits are for optional return data. 1438 * The upper 16-bits are ordered from least permissive values to most. 1439 * 1440 * The ordering ensures that a min_t() over composed return values always 1441 * selects the least permissive choice. 1442 */ 1443 enum SECCOMP_RET_KILL_PROCESS = 0x80000000U; /* kill the process immediately */ 1444 enum SECCOMP_RET_KILL_THREAD =0x00000000U; /* kill the thread immediately */ 1445 enum SECCOMP_RET_KILL = SECCOMP_RET_KILL_THREAD; /* default to killing the thread */ 1446 enum SECCOMP_RET_TRAP = 0x00030000U; /* disallow and force a SIGSYS */ 1447 enum SECCOMP_RET_ERRNO = 0x00050000U; /* returns an errno */ 1448 enum SECCOMP_RET_USER_NOTIF = 0x7fc00000U; /* notifies userspace */ 1449 enum SECCOMP_RET_TRACE = 0x7ff00000U; /* pass to a tracer or disallow */ 1450 enum SECCOMP_RET_ALLOW = 0x7fff0000U; /* allow */ 1451 1452 /* Masks for the return value sections. */ 1453 enum SECCOMP_RET_ACTION = 0x7fff0000U; 1454 enum SECCOMP_RET_DATA = 0x0000ffffU; 1455 1456 /** 1457 * struct seccomp_data - the format the BPF program executes over. 1458 * @nr: the system call number 1459 * @arch: indicates system call convention as an AUDIT_ARCH_* value 1460 * as defined in <linux/audit.h>. 1461 * @instruction_pointer: at the time of the system call. 1462 * @args: up to 6 system call arguments always stored as 64-bit values 1463 * regardless of the architecture. 1464 */ 1465 struct seccomp_data 1466 { 1467 int nr; 1468 uint arch; 1469 ulong instruction_pointer; 1470 ulong[6] args; 1471 } 1472 1473 /* rename some of the socket filter types to make more sense */ 1474 alias bpf_instr_raw = void*; // sock_filter; 1475 /+ 1476 /* no new privs defintions */ 1477 enum PR_SET_NO_NEW_PRIVS = 38; 1478 enum PR_GET_NO_NEW_PRIVS = 39; 1479 +/ 1480 enum SECCOMP_SET_MODE_STRICT = 0; 1481 enum SECCOMP_SET_MODE_FILTER = 1; 1482 enum SECCOMP_GET_ACTION_AVAIL = 2; 1483 enum SECCOMP_GET_NOTIF_SIZES = 3; 1484 1485 enum SECCOMP_FILTER_FLAG_TSYNC = (1UL << 0); 1486 enum SECCOMP_FILTER_FLAG_LOG = (1UL << 1); 1487 enum SECCOMP_FILTER_FLAG_SPEC_ALLOW = (1UL << 2); 1488 enum SECCOMP_FILTER_FLAG_NEW_LISTENER =(1UL << 3); 1489 enum SECCOMP_RET_LOG = 0x7ffc0000U; 1490 enum SECCOMP_RET_ACTION_FULL = 0xffff0000U; 1491 1492 struct seccomp_notif_sizes 1493 { 1494 ushort seccomp_notif; 1495 ushort seccomp_notif_resp; 1496 ushort seccomp_data; 1497 } 1498 1499 struct seccomp_notif 1500 { 1501 ulong id; 1502 uint pid; 1503 uint flags; 1504 seccomp_data data; 1505 } 1506 1507 struct seccomp_notif_resp 1508 { 1509 ulong id; 1510 long val; 1511 int error; 1512 uint flags; 1513 } 1514 1515 enum SECCOMP_IOC_MAGIC = '!'; 1516 // enum SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) 1517 //define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) 1518 // enum SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) 1519 // enum SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) 1520 1521 /* flags for seccomp notification fd ioctl */ 1522 // enum SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) 1523 // enum SECCOMP_IOCTL_NOTIF_SEND = SECCOMP_IOWR(1, \ seccomp_notif_resp) 1524 // enum SECCOMP_IOCTL_NOTIF_ID_VALID = SECCOMP_IOR(2, ulong) 1525 1526 int sys_chk_seccomp_syscall(); 1527 void sys_set_seccomp_syscall(int enable); 1528 int sys_chk_seccomp_action(uint action); 1529 void sys_set_seccomp_action(uint action, int enable); 1530 int sys_chk_seccomp_flag(int flag); 1531 void sys_set_seccomp_flag(int flag, int enable); 1532 int sys_filter_load(db_filter_col* col); 1533 int sys_notify_alloc(seccomp_notif** req, seccomp_notif_resp** resp); 1534 int sys_notify_receive(int fd, seccomp_notif* req); 1535 int sys_notify_respond(int fd, seccomp_notif_resp* resp); 1536 int sys_notify_id_valid(int fd, ulong id); 1537 int gen_pfc_generate(const db_filter_col* col, int fd); 1538 struct bpf_program 1539 { 1540 ushort blk_cnt; 1541 bpf_instr_raw* blks; 1542 } 1543 /+ 1544 #define BPF_PGM_SIZE(x) \ 1545 ((x)->blk_cnt * sizeof(*((x)->blks))) 1546 +/ 1547 1548 bpf_program* gen_bpf_generate(const db_filter_col* col); 1549 void gen_bpf_release(bpf_program* program); 1550 1551 uint hash(const void *key, size_t length); 1552 1553 void *zmalloc(size_t size); 1554 1555 struct db_api_arg 1556 { 1557 uint arg; 1558 SecCompCompare op; 1559 scmp_datum_t mask; 1560 scmp_datum_t datum; 1561 bool valid; 1562 } 1563 1564 struct db_api_rule_list 1565 { 1566 uint action; 1567 int syscall; 1568 bool strict; 1569 db_api_arg[ARG_COUNT_MAX] args; 1570 1571 db_api_rule_list* prev, next; 1572 } 1573 1574 struct db_arg_chain_tree 1575 { 1576 @SILdoc("argument number (a0 = 0, a1 = 1, etc.)") 1577 uint arg; 1578 1579 @SILdoc("true to indicate this is the high 32-bit word of a 64-bit value") 1580 bool arg_h_flg; 1581 1582 @SILdoc("argument bpf offset") 1583 uint arg_offset; 1584 1585 @SILdoc("comparison operator") 1586 SecCompCompare op; 1587 SecCompCompare op_orig; 1588 1589 @SILdoc("syscall argument value") 1590 uint mask; 1591 uint datum; 1592 scmp_datum_t datum_full; 1593 1594 @SILdoc("actions") 1595 bool act_t_flg; 1596 bool act_f_flg; 1597 uint act_t; 1598 uint act_f; 1599 1600 @SILdoc("list of nodes on this level") 1601 db_arg_chain_tree* lvl_prv, lvl_nxt; 1602 1603 @SILdoc("next node in the chain") 1604 db_arg_chain_tree* nxt_t; 1605 db_arg_chain_tree* nxt_f; 1606 1607 uint refcnt; 1608 } 1609 1610 enum ARG_MASK_MAX = uint.max; 1611 1612 struct db_sys_list 1613 { 1614 @SILdoc("native syscall number") 1615 uint num; 1616 1617 @SILdoc("priority - higher is better") 1618 uint priority; 1619 1620 @SILdoc("the argument chain heads") 1621 db_arg_chain_tree* chains; 1622 uint node_cnt; 1623 1624 @SILdoc("action in the case of no argument chains") 1625 uint action; 1626 1627 db_sys_list* next; 1628 1629 @SILdoc("temporary use only by the BPF generator") 1630 db_sys_list* pri_prv, pri_nxt; 1631 1632 bool valid; 1633 } 1634 1635 struct db_filter_attr 1636 { 1637 @SILdoc("action to take if we don't match an explicit allow/deny") 1638 uint act_default; 1639 1640 @SILdoc("action to take if we don't match the architecture") 1641 uint act_badarch; 1642 1643 @SILdoc("NO_NEW_PRIVS related attributes") 1644 uint nnp_enable; 1645 1646 @SILdoc("SECCOMP_FILTER_FLAG_TSYNC related attributes") 1647 uint tsync_enable; 1648 1649 @SILdoc("allow rules with a -1 syscall value") 1650 uint api_tskip; 1651 1652 @SILdoc("SECCOMP_FILTER_FLAG_LOG related attributes") 1653 uint log_enable; 1654 1655 @SILdoc("SPEC_ALLOW related attributes") 1656 uint spec_allow; 1657 } 1658 1659 struct db_filter 1660 { 1661 @SILdoc("target architecture") 1662 const(arch_def)* arch; 1663 1664 @SILdoc("syscall filters, kept as a sorted single-linked list") 1665 db_sys_list *syscalls; 1666 1667 @SILdoc("list of rules used to build the filters, kept in order") 1668 db_api_rule_list* rules; 1669 } 1670 1671 struct db_filter_snap 1672 { 1673 @SILdoc("individual filters") 1674 db_filter** filters; 1675 uint filter_cnt; 1676 1677 db_filter_snap* next; 1678 } 1679 1680 struct db_filter_col 1681 { 1682 @SILdoc("verification / state") 1683 int state; 1684 1685 @SILdoc("attributes") 1686 db_filter_attr attr; 1687 1688 @SILdoc("individual filters") 1689 int endian; 1690 db_filter* *filters; 1691 uint filter_cnt; 1692 1693 @SILdoc("transaction snapshots") 1694 db_filter_snap* snapshots; 1695 1696 @SILdoc("notification fd that was returned from seccomp()") 1697 int notify_fd; 1698 bool notify_used; 1699 } 1700 1701 /+ 1702 @SILdoc(" 1703 Iterate over each item in the DB list 1704 @param iter the iterator 1705 @param list the list 1706 1707 * This macro acts as for()/while() conditional and iterates the following 1708 * statement for each item in the given list. 1709 ")* 1710 #define db_list_foreach(iter,list) \ 1711 for (iter = (list); iter != NULL; iter = iter->next) 1712 +/ 1713 1714 db_api_rule_list* db_rule_dup(const(db_api_rule_list)* src); 1715 db_filter_col* db_col_init(uint def_action); 1716 int db_col_reset(db_filter_col* col, uint def_action); 1717 void db_col_release(db_filter_col* col); 1718 int db_col_valid(db_filter_col* col); 1719 int db_col_action_valid(const db_filter_col* col, uint action); 1720 int db_col_merge(db_filter_col* col_dst, db_filter_col* col_src); 1721 int db_col_arch_exist(db_filter_col* col, uint arch_token); 1722 int db_col_attr_get(const db_filter_col* col, FilterAttribute attr, uint *value); 1723 int db_col_attr_set(db_filter_col* col, FilterAttribute attr, uint value); 1724 1725 int db_col_db_new(db_filter_col* col, const(arch_def)* arch); 1726 int db_col_db_add(db_filter_col* col, db_filter* db); 1727 int db_col_db_remove(db_filter_col* col, uint arch_token); 1728 1729 int db_col_rule_add(db_filter_col* col, bool strict, uint action, int syscall, 1730 uint arg_cnt, const(SecCompArgCmp)* arg_array); 1731 1732 int db_col_syscall_priority(db_filter_col* col, int syscall, ubyte priority); 1733 int db_col_transaction_start(db_filter_col* col); 1734 void db_col_transaction_abort(db_filter_col* col); 1735 void db_col_transaction_commit(db_filter_col* col); 1736 int db_rule_add(db_filter* db, const(db_api_rule_list)* rule); 1737 1738 1739 struct arch_def 1740 { 1741 /* arch definition */ 1742 uint token; 1743 uint token_bpf; 1744 enum ARCH_SIZE 1745 { 1746 unspec = 0, 1747 thirtyTwo = 32, 1748 sixtyFour = 64, 1749 } 1750 ARCH_SIZE size; 1751 enum ArchEndian 1752 { 1753 unspec = 0, 1754 little = 1, 1755 big = 2, 1756 } 1757 ArchEndian endian; 1758 1759 /* arch specific functions */ 1760 int function(const(char) *name) syscall_resolve_name; 1761 const(char)* function(int num) syscall_resolve_num; 1762 int function(int *syscall) syscall_rewrite; 1763 int function(db_filter* db, db_api_rule_list* rule) rule_add; 1764 } 1765 1766 /* arch_def for the current architecture */ 1767 extern const(arch_def)* arch_def_native; 1768 1769 /* syscall name/num mapping */ 1770 struct arch_syscall_def 1771 { 1772 const(char) *name; 1773 uint num; 1774 } 1775 1776 /+ 1777 #define DATUM_MAX ((scmp_datum_t)-1) 1778 #define D64_LO(x) ((uint32_t)((uint64_t)(x) & 0x00000000ffffffff)) 1779 #define D64_HI(x) ((uint32_t)((uint64_t)(x) >> 32)) 1780 +/ 1781 1782 enum ARG_COUNT_MAX = 6; 1783 int arch_valid(uint arch); 1784 const(arch_def)* arch_def_lookup(uint token); 1785 const(arch_def)* arch_def_lookup_name(const(char) *arch_name); 1786 int arch_arg_offset_lo(const(arch_def)* arch, uint arg); 1787 int arch_arg_offset_hi(const(arch_def)* arch, uint arg); 1788 int arch_arg_offset(const(arch_def) *arch, uint arg); 1789 int arch_syscall_resolve_name(const(arch_def)* arch, const(char) *name); 1790 const(char) *arch_syscall_resolve_num(const(arch_def)* arch, int num); 1791 int arch_syscall_translate(const(arch_def)* arch, int *syscall); 1792 int arch_syscall_rewrite(const(arch_def)* arch, int *syscall); 1793 int arch_filter_rule_add(db_filter* db,const(db_api_rule_list)* rule); 1794 1795 version(X86_64) 1796 { 1797 extern const(arch_def) arch_def_x86_64; 1798 int x86_64_syscall_resolve_name(const(char) *name); 1799 const(char) *x86_64_syscall_resolve_num(int num); 1800 const(arch_syscall_def)* x86_64_syscall_iterate(uint spot); 1801 } 1802 1803 /+ 1804 1805 version(X86) 1806 { 1807 extern const struct arch_def arch_def_x86; 1808 int x86_syscall_resolve_name(const(char) *name); 1809 const(char) *x86_syscall_resolve_num(int num); 1810 const struct arch_syscall_def *x86_syscall_iterate(uint spot); 1811 int x86_syscall_rewrite(int *syscall); 1812 int x86_rule_add(db_filter* db, struct db_api_rule_list *rule); 1813 } 1814 1815 version(ARCHX32) 1816 { 1817 enum X32_SYSCALL_BIT = 0x40000000; 1818 extern const struct arch_def arch_def_x32; 1819 int x32_syscall_resolve_name(const(char) *name); 1820 const(char) *x32_syscall_resolve_num(int num); 1821 const struct arch_syscall_def *x32_syscall_iterate(uint spot); 1822 } 1823 1824 1825 version(ARM) 1826 { 1827 extern const struct arch_def arch_def_arm; 1828 int arm_syscall_resolve_name(const(char) *name); 1829 const(char) *arm_syscall_resolve_num(int num); 1830 const struct arch_syscall_def *arm_syscall_iterate(uint spot); 1831 } 1832 1833 1834 version(AARCH64) 1835 { 1836 extern const struct arch_def arch_def_aarch64; 1837 int aarch64_syscall_resolve_name(const(char) *name); 1838 const(char) *aarch64_syscall_resolve_num(int num); 1839 const(arch_syscall_def)* aarch64_syscall_iterate(uint spot); 1840 } 1841 +/ 1842