diff --git a/libcontainer/seccomp/patchbpf/enosys_linux.go b/libcontainer/seccomp/patchbpf/enosys_linux.go index 6376512b0..29302db8b 100644 --- a/libcontainer/seccomp/patchbpf/enosys_linux.go +++ b/libcontainer/seccomp/patchbpf/enosys_linux.go @@ -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!