首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在子级中安装seccomp筛选器

在子级中安装seccomp筛选器
EN

Stack Overflow用户
提问于 2020-12-05 09:56:01
回答 1查看 376关注 0票数 1

我想知道是否可以在Go程序的子进程中安装seccomp筛选器。目前我正在派生子进程,如下所示:

代码语言:javascript
复制
cmd := exec.Command(target)
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &unix.SysProcAttr{
    Ptrace: true,
}

cmd.Start()
cmd.Wait()

这可以很好地工作,并且SysProcAttr提供了一种在子进程中启用Ptrace的机制。但是,似乎没有任何支持在孩子中安装seccomp筛选器。我知道https://github.com/elastic/go-seccomp-bpfhttps://github.com/seccomp/libseccomp-golang,但这些库似乎只支持在当前进程中安装seccomp过滤器(以及从当前进程派生的任何子进程)。我只想在子进程中安装过滤器,而不是父进程,因为我不想让父进程也被沙箱保护。

在C语言中,在子进程中安装seccomp筛选器的机制是: fork,在当前进程中安装筛选器(来自子进程),然后执行。然而,在Go中似乎不支持像这样分离fork和exec。有什么方法可以解决这个问题吗?或者我需要使用C来正确地完成这个任务吗?

是否可以将SysProcAttr扩展为允许seccomp过滤器,或者允许在fork之后和exec之前运行任意代码(在某些情况下,我假设它先调用fork,然后再调用exec)?我该如何去实现它呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-17 04:58:58

我使用这里的forkexec包:https://godoc.org/github.com/criyle/go-sandbox/pkg/forkexecelastic/go-seccomp-bpf解决了这个问题。Seccomp filters可以像这样安装:

代码语言:javascript
复制
import bseccomp "github.com/elastic/go-seccomp-bpf"
import "github.com/criyle/go-sandbox/pkg/forkexec"

// ...

policy := bseccomp.Policy{
    DefaultAction: bseccomp.ActionAllow,
    Syscalls: []bseccomp.SyscallGroup{
        {
            Action: bseccomp.ActionTrace,
            Names: []string{
                "write",
            },
        },
    },
}

program, err := policy.Assemble()
must(err)
filter, err := ExportBPF(program)
must(err)

bin, err := os.Open(args[0])
must(err)
cmd := forkexec.Runner{
    Args:              args[0:],
    ExecFile:          bin.Fd(),
    Seccomp:           filter.SockFprog(),
    StopBeforeSeccomp: true,
    Ptrace:            true,
}

pid, err := cmd.Start()
must(err)
var ws unix.WaitStatus
_, err = unix.Wait4(pid, &ws, 0, nil)
must(err)

这需要使用criyle/go-sandbox/pkg/seccomp包的一些额外函数。

代码语言:javascript
复制
// ExportBPF convert libseccomp filter to kernel readable BPF content
func ExportBPF(filter []bpf.Instruction) (seccomp.Filter, error) {
    raw, err := bpf.Assemble(filter)
    if err != nil {
        return nil, err
    }
    return sockFilter(raw), nil
}

func sockFilter(raw []bpf.RawInstruction) []syscall.SockFilter {
    filter := make([]syscall.SockFilter, 0, len(raw))
    for _, instruction := range raw {
        filter = append(filter, syscall.SockFilter{
            Code: instruction.Op,
            Jt:   instruction.Jt,
            Jf:   instruction.Jf,
            K:    instruction.K,
        })
    }
    return filter
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65153051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档