SECCOMP_RET_KILL /* kill the task immediately */ SECCOMP_RET_TRAP /* disallow and force a SIGSYS */ SECCOMP_RET_ERRNO /* returns an errno */ SECCOMP_RET_TRACE /* pass to a tracer or disallow */ SECCOMP_RET_ALLOW /* allow */
/* list of allowed syscalls */ Allow(exit_group), /* exits a processs */ Allow(brk), /* for malloc(), inside libc */ Allow(mmap), /* also for malloc() */ Allow(munmap), /* for free(), inside libc */ Allow(write), /* called by printf */ Allow(fstat), /* called by printf */
/* and if we don't match above, die */ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL), };
/* list of allowed syscalls */ Allow(exit_group), /* exits a processs */ Allow(brk), /* for malloc(), inside libc */ Allow(mmap), /* also for malloc() */ Allow(munmap), /* for free(), inside libc */ Allow(write), /* called by printf */ Allow(fstat), /* called by printf */
/* and if we don't match above, die */ BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL), }; structsock_fprogfilterprog = { .len = sizeof(filter)/sizeof(filter[0]), .filter = filter };
intmain(int argc, char **argv) { char buf[1024];
/* set up the restricted environment */ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("Could not start seccomp:"); exit(1); } if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &filterprog) == -1) { perror("Could not start seccomp:"); exit(1); }
/* printf only writes to stdout, but for some reason it stats it. */ printf("hello there!\n");
/** * Kill the process */ #define SCMP_ACT_KILL 0x00000000U /** * Throw a SIGSYS signal */ #define SCMP_ACT_TRAP 0x00030000U /** * Return the specified error code */ #define SCMP_ACT_ERRNO(x) (0x00050000U | ((x) & 0x0000ffffU)) /** * Notify a tracing process with the specified value */ #define SCMP_ACT_TRACE(x) (0x7ff00000U | ((x) & 0x0000ffffU)) /** * Allow the syscall to be executed after the action has been logged */ #define SCMP_ACT_LOG 0x7ffc0000U /** * Allow the syscall to be executed */ #define SCMP_ACT_ALLOW 0x7fff0000U
seccomp_rule_add是添加一条规则,原型如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * Add a new rule to the filter * @param ctx the filter context * @param action the filter action * @param syscall the syscall number * @param arg_cnt the number of argument filters in the argument filter chain * @param ... scmp_arg_cmp structs (use of SCMP_ARG_CMP() recommended) * * This function adds a series of new argument/value checks to the seccomp * filter for the given syscall; multiple argument/value checks can be * specified and they will be chained together (AND'd together) in the filter. * If the specified rule needs to be adjusted due to architecture specifics it * will be adjusted without notification. Returns zero on success, negative * values on failure. * */ intseccomp_rule_add(scmp_filter_ctx ctx, uint32_t action, int syscall, unsignedint arg_cnt, ...);
seccomp_load是应用过滤,原型如下
1 2 3 4 5 6 7 8 9 10 11
/** * Loads the filter into the kernel * @param ctx the filter context * * This function loads the given seccomp filter context into the kernel. If * the filter was loaded correctly, the kernel will be enforcing the filter * when this function returns. Returns zero on success, negative values on * error. * */ intseccomp_load(const scmp_filter_ctx ctx);
intmain(void){ scmp_filter_ctx ctx; ctx = seccomp_init(SCMP_ACT_ALLOW); seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(write),1,SCMP_A2(SCMP_CMP_GT,0x10));//第2(从0)个参数大于0x10 seccomp_load(ctx); write(1,"i will give you a shell\n",24);//会拦截 write(1,"1234567812345678",0x10);//不被拦截 return0; }
/** * Specify an argument comparison struct for use in declaring rules * @param arg the argument number, starting at 0 * @param op the comparison operator, e.g. SCMP_CMP_* * @param datum_a dependent on comparison * @param datum_b dependent on comparison, optional */ #define SCMP_CMP(...) ((struct scmp_arg_cmp){__VA_ARGS__})
/** * Specify an argument comparison struct for argument 0 */ #define SCMP_A0(...) SCMP_CMP(0, __VA_ARGS__)
/** * Specify an argument comparison struct for argument 1 */ #define SCMP_A1(...) SCMP_CMP(1, __VA_ARGS__)
/** * Specify an argument comparison struct for argument 2 */ #define SCMP_A2(...) SCMP_CMP(2, __VA_ARGS__)
/** * Specify an argument comparison struct for argument 3 */ #define SCMP_A3(...) SCMP_CMP(3, __VA_ARGS__)
/** * Specify an argument comparison struct for argument 4 */ #define SCMP_A4(...) SCMP_CMP(4, __VA_ARGS__)
/** * Specify an argument comparison struct for argument 5 */ #define SCMP_A5(...) SCMP_CMP(5, __VA_ARGS__)
/** * Comparison operators */ enumscmp_compare { _SCMP_CMP_MIN = 0, SCMP_CMP_NE = 1, /**< not equal */ SCMP_CMP_LT = 2, /**< less than */ SCMP_CMP_LE = 3, /**< less than or equal */ SCMP_CMP_EQ = 4, /**< equal */ SCMP_CMP_GE = 5, /**< greater than or equal */ SCMP_CMP_GT = 6, /**< greater than */ SCMP_CMP_MASKED_EQ = 7, /**< masked equality */ _SCMP_CMP_MAX, };
/** * Argument datum */ typedefuint64_tscmp_datum_t;
/** * Argument / Value comparison definition */ structscmp_arg_cmp { unsignedint arg; /**< argument number, starting at 0 */ enumscmp_compareop;/**< the comparison op, e.g. SCMP_CMP_* */ scmp_datum_t datum_a; scmp_datum_t datum_b; };