aboutsummaryrefslogtreecommitdiffhomepage
path: root/helper/bwrap/seccomp-resolve.go
blob: 995a3719f8597c060a5b380ae14d2ad7598c824d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package bwrap

import (
	"fmt"
	"io"
	"os"

	"git.gensokyo.uk/security/fortify/internal/fmsg"
)

type SyscallPolicy struct {
	DenyDevel bool `json:"deny_devel"`
	Multiarch bool `json:"multiarch"`
	Linux32   bool `json:"linux32"`
	Can       bool `json:"can"`
	Bluetooth bool `json:"bluetooth"`
}

type seccompBuilder struct {
	config *Config
}

func (s *seccompBuilder) Len() int {
	if s == nil {
		return 0
	}
	return 2
}

func (s *seccompBuilder) Append(args *[]string, extraFiles *[]*os.File) error {
	if s == nil {
		return nil
	}
	if f, err := s.config.resolveSeccomp(); err != nil {
		return err
	} else {
		extraFile(args, extraFiles, positionalArgs[Seccomp], f)
		return nil
	}
}

func (c *Config) resolveSeccomp() (*os.File, error) {
	if c.Syscall == nil {
		return nil, nil
	}

	// resolve seccomp filter opts
	var (
		opts    syscallOpts
		optd    []string
		optCond = [...]struct {
			v bool
			o syscallOpts
			d string
		}{
			{!c.UserNS, flagDenyNS, "denyns"},
			{c.NewSession, flagDenyTTY, "denytty"},
			{c.Syscall.DenyDevel, flagDenyDevel, "denydevel"},
			{c.Syscall.Multiarch, flagMultiarch, "multiarch"},
			{c.Syscall.Linux32, flagLinux32, "linux32"},
			{c.Syscall.Can, flagCan, "can"},
			{c.Syscall.Bluetooth, flagBluetooth, "bluetooth"},
		}
	)
	if CPrintln != nil {
		optd = make([]string, 1, len(optCond)+1)
		optd[0] = "common"
	}
	for _, opt := range optCond {
		if opt.v {
			opts |= opt.o
			if fmsg.Verbose() {
				optd = append(optd, opt.d)
			}
		}
	}
	if CPrintln != nil {
		CPrintln(fmt.Sprintf("seccomp flags: %s", optd))
	}

	// export seccomp filter to tmpfile
	if f, err := tmpfile(); err != nil {
		return nil, err
	} else {
		return f, exportAndSeek(f, opts)
	}
}

func exportAndSeek(f *os.File, opts syscallOpts) error {
	if err := exportFilter(f.Fd(), opts); err != nil {
		return err
	}
	_, err := f.Seek(0, io.SeekStart)
	return err
}