Repository: opencontainers/runc
Pull request #2381 (2020-05-05 07:47:50)

s390x: fix big endian issue
_Note: this is a carry of https://github.com/opencontainers/runc/pull/2350_

This PR fixes a big endian issue and modify the tests accordingly.

The solution is based on the same fix as containers/crun@07bae05

alicefr: /cc @AkihiroSuda @kolyshkin 
AkihiroSuda: Needs https://github.com/cilium/ebpf/pull/91 as well?

alicefr: yes, otherwise the ebpf library still generates the wrong position for src and dst registers on s390x. I'll check with @iii-i, what is blocking or the TODOs for that PR

AkihiroSuda: https://github.com/cilium/ebpf/pull/91 seems merged.

AkihiroSuda: Was this closed by mistake?

alicefr: oh my god. I have something wrong with my git setup. When I force push, it wrongly updates this PR. Not sure why?!

Patch:
diff --git a/go.mod b/go.mod
index a7472228..56beebfc 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.14
 
 require (
 	github.com/checkpoint-restore/go-criu v0.0.0-20191125063657-fcdcd07065c5
-	github.com/cilium/ebpf v0.0.0-20200319110858-a7172c01168f
+	github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3
 	github.com/containerd/console v1.0.0
 	github.com/coreos/go-systemd/v22 v22.0.0
 	github.com/cyphar/filepath-securejoin v0.2.2
diff --git a/go.sum b/go.sum
index 55f649cf..3e71b19d 100644
--- a/go.sum
+++ b/go.sum
@@ -3,6 +3,8 @@ github.com/checkpoint-restore/go-criu v0.0.0-20191125063657-fcdcd07065c5 h1:950d
 github.com/checkpoint-restore/go-criu v0.0.0-20191125063657-fcdcd07065c5/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
 github.com/cilium/ebpf v0.0.0-20200319110858-a7172c01168f h1:W1RQPz3nR8RxUw/Uqk71GU3JlZ7pNa1pXrHs98h0o9U=
 github.com/cilium/ebpf v0.0.0-20200319110858-a7172c01168f/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
+github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3 h1:qcqzLJa2xCo9sgdCzpT/SJSYxROTEstuhf7ZBHMirms=
+github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
 github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ=
 github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
 github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
diff --git a/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go b/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
index 847ce8ef..5a1cdd91 100644
--- a/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
+++ b/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go
@@ -49,7 +49,8 @@ func (p *program) init() {
 	*/
 	// R2 <- type (lower 16 bit of u32 access_type at R1[0])
 	p.insts = append(p.insts,
-		asm.LoadMem(asm.R2, asm.R1, 0, asm.Half))
+		asm.LoadMem(asm.R2, asm.R1, 0, asm.Word),
+		asm.And.Imm32(asm.R2, 0xFFFF))
 
 	// R3 <- access (upper 16 bit of u32 access_type at R1[0])
 	p.insts = append(p.insts,
diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go
index 644de428..8058c157 100644
--- a/vendor/github.com/cilium/ebpf/asm/instruction.go
+++ b/vendor/github.com/cilium/ebpf/asm/instruction.go
@@ -3,6 +3,7 @@ package asm
 import (
 	"encoding/binary"
 	"fmt"
+	"github.com/cilium/ebpf/internal"
 	"io"
 	"math"
 	"strings"
@@ -433,15 +434,27 @@ type bpfInstruction struct {
 type bpfRegisters uint8
 
 func newBPFRegisters(dst, src Register) bpfRegisters {
-	return bpfRegisters((src << 4) | (dst & 0xF))
+	if internal.NativeEndian == binary.LittleEndian {
+		return bpfRegisters((src << 4) | (dst & 0xF))
+	} else {
+		return bpfRegisters((dst << 4) | (src & 0xF))
+	}
 }
 
 func (r bpfRegisters) Dst() Register {
-	return Register(r & 0xF)
+	if internal.NativeEndian == binary.LittleEndian {
+		return Register(r & 0xF)
+	}else {
+		return Register(r >> 4)
+	}
 }
 
 func (r bpfRegisters) Src() Register {
-	return Register(r >> 4)
+	if internal.NativeEndian == binary.LittleEndian {
+		return Register(r >> 4)
+	} else {
+		return Register(r & 0xf)
+	}
 }
 
 type unreferencedSymbolError struct {
diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
index 7efbbd72..89baae2b 100644
--- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
+++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
@@ -36,6 +36,7 @@ const (
 	PERF_SAMPLE_RAW          = linux.PERF_SAMPLE_RAW
 	PERF_FLAG_FD_CLOEXEC     = linux.PERF_FLAG_FD_CLOEXEC
 	RLIM_INFINITY            = linux.RLIM_INFINITY
+	RLIMIT_MEMLOCK           = linux.RLIMIT_MEMLOCK
 )
 
 // Statfs_t is a wrapper
diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
index 7961b356..8fc8e77a 100644
--- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
+++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
@@ -38,6 +38,7 @@ const (
 	PERF_SAMPLE_RAW          = 0x400
 	PERF_FLAG_FD_CLOEXEC     = 0x8
 	RLIM_INFINITY            = 0x7fffffffffffffff
+	RLIMIT_MEMLOCK           = 8
 )
 
 // Statfs_t is a wrapper
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 15358296..457f6644 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,7 +1,7 @@
 # github.com/checkpoint-restore/go-criu v0.0.0-20191125063657-fcdcd07065c5
 ## explicit
 github.com/checkpoint-restore/go-criu/rpc
-# github.com/cilium/ebpf v0.0.0-20200319110858-a7172c01168f
+# github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3
 ## explicit
 github.com/cilium/ebpf
 github.com/cilium/ebpf/asm


Test patch:
diff --git a/libcontainer/cgroups/ebpf/devicefilter/devicefilter_test.go b/libcontainer/cgroups/ebpf/devicefilter/devicefilter_test.go
index 59ff4b49..dfe56a37 100644
--- a/libcontainer/cgroups/ebpf/devicefilter/devicefilter_test.go
+++ b/libcontainer/cgroups/ebpf/devicefilter/devicefilter_test.go
@@ -39,15 +39,16 @@ func testDeviceFilter(t testing.TB, devices []*configs.Device, expectedStr strin
 func TestDeviceFilter_Nil(t *testing.T) {
 	expected := `
 // load parameters into registers
-        0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
-        1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
-        2: RSh32Imm dst: r3 imm: 16
-        3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
-        4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
+        0: LdXMemW dst: r2 src: r1 off: 0 imm: 0
+        1: And32Imm dst: r2 imm: 65535
+        2: LdXMemW dst: r3 src: r1 off: 0 imm: 0
+        3: RSh32Imm dst: r3 imm: 16
+        4: LdXMemW dst: r4 src: r1 off: 4 imm: 0
+        5: LdXMemW dst: r5 src: r1 off: 8 imm: 0
 block-0:
 // return 0 (reject)
-        5: Mov32Imm dst: r0 imm: 0
-        6: Exit
+        6: Mov32Imm dst: r0 imm: 0
+        7: Exit
 	`
 	testDeviceFilter(t, nil, expected)
 }
@@ -55,91 +56,92 @@ block-0:
 func TestDeviceFilter_BuiltInAllowList(t *testing.T) {
 	expected := `
 // load parameters into registers
-         0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
-         1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
-         2: RSh32Imm dst: r3 imm: 16
-         3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
-         4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
+         0: LdXMemW dst: r2 src: r1 off: 0 imm: 0
+         1: And32Imm dst: r2 imm: 65535
+         2: LdXMemW dst: r3 src: r1 off: 0 imm: 0
+         3: RSh32Imm dst: r3 imm: 16
+         4: LdXMemW dst: r4 src: r1 off: 4 imm: 0
+         5: LdXMemW dst: r5 src: r1 off: 8 imm: 0
 block-0:
 // tuntap (c, 10, 200, rwm, allow)
-         5: JNEImm dst: r2 off: -1 imm: 2 <block-1>
-         6: JNEImm dst: r4 off: -1 imm: 10 <block-1>
-         7: JNEImm dst: r5 off: -1 imm: 200 <block-1>
-         8: Mov32Imm dst: r0 imm: 1
-         9: Exit
+         6: JNEImm dst: r2 off: -1 imm: 2 <block-1>
+         7: JNEImm dst: r4 off: -1 imm: 10 <block-1>
+         8: JNEImm dst: r5 off: -1 imm: 200 <block-1>
+         9: Mov32Imm dst: r0 imm: 1
+        10: Exit
 block-1:
-        10: JNEImm dst: r2 off: -1 imm: 2 <block-2>
-        11: JNEImm dst: r4 off: -1 imm: 5 <block-2>
-        12: JNEImm dst: r5 off: -1 imm: 2 <block-2>
-        13: Mov32Imm dst: r0 imm: 1
-        14: Exit
+        11: JNEImm dst: r2 off: -1 imm: 2 <block-2>
+        12: JNEImm dst: r4 off: -1 imm: 5 <block-2>
+        13: JNEImm dst: r5 off: -1 imm: 2 <block-2>
+        14: Mov32Imm dst: r0 imm: 1
+        15: Exit
 block-2:
 // /dev/pts (c, 136, wildcard, rwm, true)
-        15: JNEImm dst: r2 off: -1 imm: 2 <block-3>
-        16: JNEImm dst: r4 off: -1 imm: 136 <block-3>
-        17: Mov32Imm dst: r0 imm: 1
-        18: Exit
+        16: JNEImm dst: r2 off: -1 imm: 2 <block-3>
+        17: JNEImm dst: r4 off: -1 imm: 136 <block-3>
+        18: Mov32Imm dst: r0 imm: 1
+        19: Exit
 block-3:
-        19: JNEImm dst: r2 off: -1 imm: 2 <block-4>
-        20: JNEImm dst: r4 off: -1 imm: 5 <block-4>
-        21: JNEImm dst: r5 off: -1 imm: 1 <block-4>
-        22: Mov32Imm dst: r0 imm: 1
-        23: Exit
+        20: JNEImm dst: r2 off: -1 imm: 2 <block-4>
+        21: JNEImm dst: r4 off: -1 imm: 5 <block-4>
+        22: JNEImm dst: r5 off: -1 imm: 1 <block-4>
+        23: Mov32Imm dst: r0 imm: 1
+        24: Exit
 block-4:
-        24: JNEImm dst: r2 off: -1 imm: 2 <block-5>
-        25: JNEImm dst: r4 off: -1 imm: 1 <block-5>
-        26: JNEImm dst: r5 off: -1 imm: 9 <block-5>
-        27: Mov32Imm dst: r0 imm: 1
-        28: Exit
+        25: JNEImm dst: r2 off: -1 imm: 2 <block-5>
+        26: JNEImm dst: r4 off: -1 imm: 1 <block-5>
+        27: JNEImm dst: r5 off: -1 imm: 9 <block-5>
+        28: Mov32Imm dst: r0 imm: 1
+        29: Exit
 block-5:
-        29: JNEImm dst: r2 off: -1 imm: 2 <block-6>
-        30: JNEImm dst: r4 off: -1 imm: 1 <block-6>
-        31: JNEImm dst: r5 off: -1 imm: 5 <block-6>
-        32: Mov32Imm dst: r0 imm: 1
-        33: Exit
+        30: JNEImm dst: r2 off: -1 imm: 2 <block-6>
+        31: JNEImm dst: r4 off: -1 imm: 1 <block-6>
+        32: JNEImm dst: r5 off: -1 imm: 5 <block-6>
+        33: Mov32Imm dst: r0 imm: 1
+        34: Exit
 block-6:
-        34: JNEImm dst: r2 off: -1 imm: 2 <block-7>
-        35: JNEImm dst: r4 off: -1 imm: 5 <block-7>
-        36: JNEImm dst: r5 off: -1 imm: 0 <block-7>
-        37: Mov32Imm dst: r0 imm: 1
-        38: Exit
+        35: JNEImm dst: r2 off: -1 imm: 2 <block-7>
+        36: JNEImm dst: r4 off: -1 imm: 5 <block-7>
+        37: JNEImm dst: r5 off: -1 imm: 0 <block-7>
+        38: Mov32Imm dst: r0 imm: 1
+        39: Exit
 block-7:
-        39: JNEImm dst: r2 off: -1 imm: 2 <block-8>
-        40: JNEImm dst: r4 off: -1 imm: 1 <block-8>
-        41: JNEImm dst: r5 off: -1 imm: 7 <block-8>
-        42: Mov32Imm dst: r0 imm: 1
-        43: Exit
+        40: JNEImm dst: r2 off: -1 imm: 2 <block-8>
+        41: JNEImm dst: r4 off: -1 imm: 1 <block-8>
+        42: JNEImm dst: r5 off: -1 imm: 7 <block-8>
+        43: Mov32Imm dst: r0 imm: 1
+        44: Exit
 block-8:
-        44: JNEImm dst: r2 off: -1 imm: 2 <block-9>
-        45: JNEImm dst: r4 off: -1 imm: 1 <block-9>
-        46: JNEImm dst: r5 off: -1 imm: 8 <block-9>
-        47: Mov32Imm dst: r0 imm: 1
-        48: Exit
+        45: JNEImm dst: r2 off: -1 imm: 2 <block-9>
+        46: JNEImm dst: r4 off: -1 imm: 1 <block-9>
+        47: JNEImm dst: r5 off: -1 imm: 8 <block-9>
+        48: Mov32Imm dst: r0 imm: 1
+        49: Exit
 block-9:
-        49: JNEImm dst: r2 off: -1 imm: 2 <block-10>
-        50: JNEImm dst: r4 off: -1 imm: 1 <block-10>
-        51: JNEImm dst: r5 off: -1 imm: 3 <block-10>
-        52: Mov32Imm dst: r0 imm: 1
-        53: Exit
+        50: JNEImm dst: r2 off: -1 imm: 2 <block-10>
+        51: JNEImm dst: r4 off: -1 imm: 1 <block-10>
+        52: JNEImm dst: r5 off: -1 imm: 3 <block-10>
+        53: Mov32Imm dst: r0 imm: 1
+        54: Exit
 block-10:
 // (b, wildcard, wildcard, m, true)
-        54: JNEImm dst: r2 off: -1 imm: 1 <block-11>
-        55: Mov32Reg dst: r1 src: r3
-        56: And32Imm dst: r1 imm: 1
-        57: JEqImm dst: r1 off: -1 imm: 0 <block-11>
-        58: Mov32Imm dst: r0 imm: 1
-        59: Exit
+        55: JNEImm dst: r2 off: -1 imm: 1 <block-11>
+        56: Mov32Reg dst: r1 src: r3
+        57: And32Imm dst: r1 imm: 1
+        58: JEqImm dst: r1 off: -1 imm: 0 <block-11>
+        59: Mov32Imm dst: r0 imm: 1
+        60: Exit
 block-11:
 // (c, wildcard, wildcard, m, true)
-        60: JNEImm dst: r2 off: -1 imm: 2 <block-12>
-        61: Mov32Reg dst: r1 src: r3
-        62: And32Imm dst: r1 imm: 1
-        63: JEqImm dst: r1 off: -1 imm: 0 <block-12>
-        64: Mov32Imm dst: r0 imm: 1
-        65: Exit
+        61: JNEImm dst: r2 off: -1 imm: 2 <block-12>
+        62: Mov32Reg dst: r1 src: r3
+        63: And32Imm dst: r1 imm: 1
+        64: JEqImm dst: r1 off: -1 imm: 0 <block-12>
+        65: Mov32Imm dst: r0 imm: 1
+        66: Exit
 block-12:
-        66: Mov32Imm dst: r0 imm: 0
-        67: Exit
+        67: Mov32Imm dst: r0 imm: 0
+        68: Exit
 `
 	testDeviceFilter(t, specconv.AllowedDevices, expected)
 }
@@ -157,15 +159,16 @@ func TestDeviceFilter_Privileged(t *testing.T) {
 	expected :=
 		`
 // load parameters into registers
-        0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
-        1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
-        2: RSh32Imm dst: r3 imm: 16
-        3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
-        4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
+        0: LdXMemW dst: r2 src: r1 off: 0 imm: 0
+        1: And32Imm dst: r2 imm: 65535
+        2: LdXMemW dst: r3 src: r1 off: 0 imm: 0
+        3: RSh32Imm dst: r3 imm: 16
+        4: LdXMemW dst: r4 src: r1 off: 4 imm: 0
+        5: LdXMemW dst: r5 src: r1 off: 8 imm: 0
 block-0:
 // return 1 (accept)
-        5: Mov32Imm dst: r0 imm: 1
-        6: Exit
+        6: Mov32Imm dst: r0 imm: 1
+        7: Exit
 	`
 	testDeviceFilter(t, devices, expected)
 }
@@ -189,22 +192,23 @@ func TestDeviceFilter_PrivilegedExceptSingleDevice(t *testing.T) {
 	}
 	expected := `
 // load parameters into registers
-         0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
-         1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
-         2: RSh32Imm dst: r3 imm: 16
-         3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
-         4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
+         0: LdXMemW dst: r2 src: r1 off: 0 imm: 0
+         1: And32Imm dst: r2 imm: 65535
+         2: LdXMemW dst: r3 src: r1 off: 0 imm: 0
+         3: RSh32Imm dst: r3 imm: 16
+         4: LdXMemW dst: r4 src: r1 off: 4 imm: 0
+         5: LdXMemW dst: r5 src: r1 off: 8 imm: 0
 block-0:
 // return 0 (reject) if type==b && major == 8 && minor == 0
-         5: JNEImm dst: r2 off: -1 imm: 1 <block-1>
-         6: JNEImm dst: r4 off: -1 imm: 8 <block-1>
-         7: JNEImm dst: r5 off: -1 imm: 0 <block-1>
-         8: Mov32Imm dst: r0 imm: 0
-         9: Exit
+         6: JNEImm dst: r2 off: -1 imm: 1 <block-1>
+         7: JNEImm dst: r4 off: -1 imm: 8 <block-1>
+         8: JNEImm dst: r5 off: -1 imm: 0 <block-1>
+         9: Mov32Imm dst: r0 imm: 0
+        10: Exit
 block-1:
 // return 1 (accept)
-        10: Mov32Imm dst: r0 imm: 1
-        11: Exit
+        11: Mov32Imm dst: r0 imm: 1
+        12: Exit
 `
 	testDeviceFilter(t, devices, expected)
 }
@@ -237,22 +241,23 @@ func TestDeviceFilter_Weird(t *testing.T) {
 	// This conforms to runc v1.0.0-rc.9 (cgroup1) behavior.
 	expected := `
 // load parameters into registers
-         0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
-         1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
-         2: RSh32Imm dst: r3 imm: 16
-         3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
-         4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
+         0: LdXMemW dst: r2 src: r1 off: 0 imm: 0
+         1: And32Imm dst: r2 imm: 65535
+         2: LdXMemW dst: r3 src: r1 off: 0 imm: 0
+         3: RSh32Imm dst: r3 imm: 16
+         4: LdXMemW dst: r4 src: r1 off: 4 imm: 0
+         5: LdXMemW dst: r5 src: r1 off: 8 imm: 0
 block-0:
 // return 0 (reject) if type==b && major == 8 && minor == 2
-         5: JNEImm dst: r2 off: -1 imm: 1 <block-1>
-         6: JNEImm dst: r4 off: -1 imm: 8 <block-1>
-         7: JNEImm dst: r5 off: -1 imm: 2 <block-1>
-         8: Mov32Imm dst: r0 imm: 0
-         9: Exit
+         6: JNEImm dst: r2 off: -1 imm: 1 <block-1>
+         7: JNEImm dst: r4 off: -1 imm: 8 <block-1>
+         8: JNEImm dst: r5 off: -1 imm: 2 <block-1>
+         9: Mov32Imm dst: r0 imm: 0
+        10: Exit
 block-1:
 // return 1 (accept)
-        10: Mov32Imm dst: r0 imm: 1
-        11: Exit
+        11: Mov32Imm dst: r0 imm: 1
+        12: Exit
 `
 	testDeviceFilter(t, devices, expected)
 }
diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh
index daac404c..e60c35e2 100644
--- a/vendor/github.com/cilium/ebpf/run-tests.sh
+++ b/vendor/github.com/cilium/ebpf/run-tests.sh
@@ -44,7 +44,7 @@ readonly tmp_dir="${TMPDIR:-$(mktemp -d)}"
 
 test -e "${tmp_dir}/${kernel}" || {
   echo Fetching "${kernel}"
-  curl --fail -L "https://github.com/newtools/ci-kernels/blob/master/${kernel}?raw=true" -o "${tmp_dir}/${kernel}"
+  curl --fail -L "https://github.com/cilium/ci-kernels/blob/master/${kernel}?raw=true" -o "${tmp_dir}/${kernel}"
 }
 
 echo Testing on "${kernel_version}"