mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
seccomp: patchbpf: minor cleanups
Define sizeof(int) as a constant, and also return ENOSYS earlier in the filter if it doesn't increase the number of instructions we generate (this is a negligible performance improvement but it does make it easier to understand the generated filter stub). Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
@@ -80,6 +80,9 @@ import "C"
|
||||
|
||||
var retErrnoEnosys = uint32(C.C_ACT_ERRNO_ENOSYS)
|
||||
|
||||
// Assume sizeof(int) == 4 in the BPF program.
|
||||
const bpfSizeofInt = 4
|
||||
|
||||
// This syscall is used for multiplexing "large" syscalls on s390(x). Unknown
|
||||
// syscalls will end up with this syscall number, so we need to explcitly
|
||||
// return -ENOSYS for this syscall on those architectures.
|
||||
@@ -99,7 +102,6 @@ func isAllowAction(action configs.Action) bool {
|
||||
|
||||
func parseProgram(rdr io.Reader) ([]bpf.RawInstruction, error) {
|
||||
var program []bpf.RawInstruction
|
||||
loop:
|
||||
for {
|
||||
// Read the next instruction. We have to use NativeEndian because
|
||||
// seccomp_export_bpf outputs the program in *host* endian-ness.
|
||||
@@ -107,7 +109,7 @@ loop:
|
||||
if err := binary.Read(rdr, utils.NativeEndian, &insn); err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
// Parsing complete.
|
||||
break loop
|
||||
break
|
||||
}
|
||||
if errors.Is(err, io.ErrUnexpectedEOF) {
|
||||
// Parsing stopped mid-instruction.
|
||||
@@ -321,7 +323,7 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
// share this code between architecture branches.
|
||||
section := []bpf.Instruction{
|
||||
// load [0] (syscall number)
|
||||
bpf.LoadAbsolute{Off: 0, Size: 4}, // NOTE: We assume sizeof(int) == 4.
|
||||
bpf.LoadAbsolute{Off: 0, Size: bpfSizeofInt},
|
||||
}
|
||||
|
||||
switch len(maxSyscalls) {
|
||||
@@ -381,8 +383,8 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
sectionTail = []bpf.Instruction{
|
||||
// jle [syscall],1
|
||||
bpf.JumpIf{Cond: bpf.JumpLessOrEqual, Val: uint32(sysno), SkipTrue: 1},
|
||||
// ja [baseJumpEnosys+1]
|
||||
bpf.Jump{Skip: baseJumpEnosys + 1},
|
||||
// ret [ENOSYS]
|
||||
bpf.RetConstant{Val: retErrnoEnosys},
|
||||
// ja [baseJumpFilter]
|
||||
bpf.Jump{Skip: baseJumpFilter},
|
||||
}
|
||||
@@ -466,7 +468,7 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
// jset (1<<30),1
|
||||
// jgt [x86 syscall],1,2
|
||||
// jle [x32 syscall],1
|
||||
// ja [baseJumpEnosys+1]
|
||||
// ret [ENOSYS]
|
||||
// ja [baseJumpFilter]
|
||||
section = append(section, []bpf.Instruction{
|
||||
// jset (1<<30),1
|
||||
@@ -477,14 +479,14 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
Val: uint32(x86sysno),
|
||||
SkipTrue: 1, SkipFalse: 2,
|
||||
},
|
||||
// jle [x32 syscall],[baseJumpEnosys]
|
||||
// jle [x32 syscall],1
|
||||
bpf.JumpIf{
|
||||
Cond: bpf.JumpLessOrEqual,
|
||||
Val: uint32(x32sysno),
|
||||
SkipTrue: 1,
|
||||
},
|
||||
// ja [baseJumpEnosys+1]
|
||||
bpf.Jump{Skip: baseJumpEnosys + 1},
|
||||
// ret [ENOSYS]
|
||||
bpf.RetConstant{Val: retErrnoEnosys},
|
||||
// ja [baseJumpFilter]
|
||||
bpf.Jump{Skip: baseJumpFilter},
|
||||
}...)
|
||||
@@ -549,7 +551,7 @@ func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error)
|
||||
// Prepend the load instruction for the architecture.
|
||||
programTail = append([]bpf.Instruction{
|
||||
// load [4] (architecture)
|
||||
bpf.LoadAbsolute{Off: 4, Size: 4}, // NOTE: We assume sizeof(int) == 4.
|
||||
bpf.LoadAbsolute{Off: bpfSizeofInt, Size: bpfSizeofInt},
|
||||
}, programTail...)
|
||||
|
||||
// And that's all folks!
|
||||
|
||||
Reference in New Issue
Block a user