You need to enable JavaScript to run this app. 如何从C语言或终端为目标进程单独应用seccomp安全规则
优惠活动
大模型
产品
解决方案
定价
更多

如何从C语言或终端为目标进程单独应用seccomp安全规则

问题根因

你当前的执行顺序是「加载seccomp规则」→「调用execl执行目标命令」,而seccomp规则加载后会立即对当前进程的所有后续系统调用生效,execl执行过程中需要的系统调用(比如内部调用的execve,动态编译场景下的其他依赖调用)不在你允许的规则里,就会被拦截。

方案1:C语言原生实现

核心修改逻辑:构造seccomp规则时额外允许当前进程调用execve,保证execl正常运行,当前进程执行execve之后,生成的目标命令进程会继承剩余的严格seccomp规则。

前置依赖

先安装libseccomp开发库:
sudo apt install libseccomp-dev

完整代码示例

#include <seccomp.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    scmp_filter_ctx filter;
    // 初始化过滤器,默认违反规则直接杀死进程
    filter = seccomp_init(SCMP_ACT_KILL);
    if (filter == NULL) {
        perror("seccomp_init failed");
        return 1;
    }

    // 允许当前进程执行execve,保证execl正常运行
    if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(execve), 0) != 0) {
        perror("add execve rule failed");
        goto err;
    }

    // 目标命令允许规则:仅允许向stdout(1)、stderr(2)写内容
    if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
        SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
        perror("add write rule failed");
        goto err;
    }

    // 允许进程退出相关系统调用
    if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0) != 0) {
        perror("add exit rule failed");
        goto err;
    }

    // --- 如果目标程序是动态链接,需要取消注释以下规则,允许加载动态库 ---
    /*
    if (seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(open), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(access), 0) != 0 ||
        seccomp_rule_add(filter, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0) != 0) {
        perror("add dynamic link rule failed");
        goto err;
    }
    */

    // 加载seccomp规则
    if (seccomp_load(filter) != 0) {
        perror("seccomp_load failed");
        goto err;
    }

    // 执行目标命令,注意execl第一个参数为程序路径,最后一个参数必须为NULL
    execl("/bin/ls", "ls", NULL);
    perror("execl failed");

err:
    seccomp_release(filter);
    return 1;
}

编译命令

gcc -o seccomp_runner seccomp_runner.c -lseccomp

注意:如果要求目标命令完全禁止读写任何文件,目标命令必须是静态编译的,否则动态链接过程需要读取系统动态库文件,必然会触发文件读操作,无法正常启动。


方案2:现成工具实现(无需写C代码)

Ubuntu 18.04可以直接用firejail工具快速实现需求:

  1. 安装firejail:sudo apt install firejail
  2. 运行命令示例:
firejail --seccomp --private=/tmp/empty --read-only=/ --allow=/dev/stdout --allow=/dev/stderr ls

该配置会自动为目标进程加载seccomp规则,禁止所有未授权的系统调用,仅允许写入控制台,无法读写其他文件。

内容的提问来源于stack exchange,提问作者user100123122

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 20:24:03