github.com/criyle/go-sandbox@v0.10.3/pkg/seccomp/libseccomp/builder_linux.go (about)

     1  package libseccomp
     2  
     3  import (
     4  	"syscall"
     5  
     6  	"github.com/criyle/go-sandbox/pkg/seccomp"
     7  	libseccomp "github.com/elastic/go-seccomp-bpf"
     8  	"golang.org/x/net/bpf"
     9  )
    10  
    11  // Builder is used to build the filter
    12  type Builder struct {
    13  	Allow, Trace []string
    14  	Default      Action
    15  }
    16  
    17  var actTrace = libseccomp.ActionTrace
    18  
    19  // Build builds the filter
    20  func (b *Builder) Build() (seccomp.Filter, error) {
    21  	policy := libseccomp.Policy{
    22  		DefaultAction: ToSeccompAction(b.Default),
    23  		Syscalls: []libseccomp.SyscallGroup{
    24  			{
    25  				Action: libseccomp.ActionAllow,
    26  				Names:  b.Allow,
    27  			},
    28  			{
    29  				Action: actTrace,
    30  				Names:  b.Trace,
    31  			},
    32  		},
    33  	}
    34  	program, err := policy.Assemble()
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	return ExportBPF(program)
    39  }
    40  
    41  // ExportBPF convert libseccomp filter to kernel readable BPF content
    42  func ExportBPF(filter []bpf.Instruction) (seccomp.Filter, error) {
    43  	raw, err := bpf.Assemble(filter)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	return sockFilter(raw), nil
    48  }
    49  
    50  func sockFilter(raw []bpf.RawInstruction) []syscall.SockFilter {
    51  	filter := make([]syscall.SockFilter, 0, len(raw))
    52  	for _, instruction := range raw {
    53  		filter = append(filter, syscall.SockFilter{
    54  			Code: instruction.Op,
    55  			Jt:   instruction.Jt,
    56  			Jf:   instruction.Jf,
    57  			K:    instruction.K,
    58  		})
    59  	}
    60  	return filter
    61  }