aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/seccomp/proc.go
blob: e4ce18536cda451aaac6d440fa30e0d2df8379da (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
package seccomp

import (
	"context"
	"errors"
	"syscall"

	"git.gensokyo.uk/security/hakurei/helper/proc"
)

const (
	PresetStrict = PresetExt | PresetDenyNS | PresetDenyTTY | PresetDenyDevel
)

// New returns an inactive Encoder instance.
func New(rules []NativeRule, flags ExportFlag) *Encoder { return &Encoder{newExporter(rules, flags)} }

// Load loads a filter into the kernel.
func Load(rules []NativeRule, flags ExportFlag) error { return Export(-1, rules, flags) }

/*
An Encoder writes a BPF program to an output stream.

Methods of Encoder are not safe for concurrent use.

An Encoder must not be copied after first use.
*/
type Encoder struct {
	*exporter
}

func (e *Encoder) Read(p []byte) (n int, err error) {
	if err = e.prepare(); err != nil {
		return
	}
	return e.r.Read(p)
}

func (e *Encoder) Close() error {
	if e.r == nil {
		return syscall.EINVAL
	}

	// this hangs if the cgo thread fails to exit
	return errors.Join(e.closeWrite(), <-e.exportErr)
}

// NewFile returns an instance of exporter implementing [proc.File].
func NewFile(rules []NativeRule, flags ExportFlag) proc.File {
	return &File{rules: rules, flags: flags}
}

// File implements [proc.File] and provides access to the read end of exporter pipe.
type File struct {
	rules []NativeRule
	flags ExportFlag
	proc.BaseFile
}

func (f *File) ErrCount() int { return 2 }
func (f *File) Fulfill(ctx context.Context, dispatchErr func(error)) error {
	e := newExporter(f.rules, f.flags)
	if err := e.prepare(); err != nil {
		return err
	}
	f.Set(e.r)
	go func() {
		select {
		case err := <-e.exportErr:
			dispatchErr(nil)
			dispatchErr(err)
		case <-ctx.Done():
			dispatchErr(e.closeWrite())
			dispatchErr(<-e.exportErr)
		}
	}()
	return nil
}