Skip to content

Commit

Permalink
TEST: Add runc patch to 1.0.8
Browse files Browse the repository at this point in the history
This change adds patches from
opencontainers/runc#2871 to 1.0.8.
  • Loading branch information
zmrow committed Apr 23, 2021
1 parent fee7e75 commit 3eba03b
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
From 7b3e0bcf2907c29e67eb49fb7ef6c03ea6456d45 Mon Sep 17 00:00:00 2001
From: Danail Branekov <danailster@gmail.com>
Date: Thu, 25 Mar 2021 10:53:03 +0000
Subject: [PATCH] Ensure the scratch pipe is read during ExportBPF

There is a potential deadlock where the ExportBPF method call writes to
a pipe but the pipe is not read until after the method call returns.
ExportBPF might fill the pipe buffer, in which case it will block
waiting for a read on the other side which can't happen until the method
returns.

Here we concurrently read from the pipe into a buffer to ensure
ExportBPF will always return.

Co-authored-by: Kieron Browne <kbrowne@vmware.com>
Co-authored-by: Danail Branekov <danailster@gmail.com>
Signed-off-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Danail Branekov <danailster@gmail.com>
---
libcontainer/seccomp/patchbpf/enosys_linux.go | 15 ++++++++++++++-
.../seccomp/patchbpf/enosys_linux_test.go | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/libcontainer/seccomp/patchbpf/enosys_linux.go b/libcontainer/seccomp/patchbpf/enosys_linux.go
index a18761031f..f074ad4d81 100644
--- a/libcontainer/seccomp/patchbpf/enosys_linux.go
+++ b/libcontainer/seccomp/patchbpf/enosys_linux.go
@@ -3,6 +3,7 @@
package patchbpf

import (
+ "bytes"
"encoding/binary"
"io"
"os"
@@ -114,14 +115,26 @@ func disassembleFilter(filter *libseccomp.ScmpFilter) ([]bpf.Instruction, error)
defer wtr.Close()
defer rdr.Close()

+ readerBuffer := new(bytes.Buffer)
+ errChan := make(chan error, 1)
+ go func() {
+ _, err := io.Copy(readerBuffer, rdr)
+ errChan <- err
+ close(errChan)
+ }()
+
if err := filter.ExportBPF(wtr); err != nil {
return nil, errors.Wrap(err, "exporting BPF")
}
// Close so that the reader actually gets EOF.
_ = wtr.Close()

+ if copyErr := <-errChan; copyErr != nil {
+ return nil, errors.Wrap(copyErr, "reading from ExportBPF pipe")
+ }
+
// Parse the instructions.
- rawProgram, err := parseProgram(rdr)
+ rawProgram, err := parseProgram(readerBuffer)
if err != nil {
return nil, errors.Wrap(err, "parsing generated BPF filter")
}
diff --git a/libcontainer/seccomp/patchbpf/enosys_linux_test.go b/libcontainer/seccomp/patchbpf/enosys_linux_test.go
index f9a4bf63fa..5c79a56ba0 100644
--- a/libcontainer/seccomp/patchbpf/enosys_linux_test.go
+++ b/libcontainer/seccomp/patchbpf/enosys_linux_test.go
@@ -281,3 +281,21 @@ func TestEnosysStub_MultiArch(t *testing.T) {
}
}
}
+
+func TestPatchHugeSeccompFilterDoesNotBlock(t *testing.T) {
+ hugeFilter, err := libseccomp.NewFilter(libseccomp.ActAllow)
+ if err != nil {
+ t.Fatalf("failed to create seccomp filter: %v", err)
+ }
+
+ for i := 1; i < 10000; i++ {
+ if err := hugeFilter.AddRule(libseccomp.ScmpSyscall(i), libseccomp.ActKill); err != nil {
+ t.Fatalf("failed to add rule to filter %d: %v", i, err)
+ }
+ }
+
+ config := fakeConfig(configs.Kill, []string{}, []string{"amd64"})
+ PatchAndLoad(config, hugeFilter)
+
+ // if we exit, we did not block
+}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
From 08b5279797d947f1507d3e04a7af0f37e6c1cec5 Mon Sep 17 00:00:00 2001
From: Kieron Browne <kbrowne@vmware.com>
Date: Thu, 25 Mar 2021 14:03:00 +0000
Subject: [PATCH] Make test specific to disassembleFilter function

TestPatchHugeSeccompFilterDoesNotBlock is only testing the
disassembleFilter function. There is no need to invoke PatchAndLoad
which has the side effect of loading a seccomp profile.

Co-authored-by: Danail Branekov <danailster@gmail.com>
Co-authored-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Kieron Browne <kbrowne@vmware.com>
Signed-off-by: Danail Branekov <danailster@gmail.com>
---
libcontainer/seccomp/patchbpf/enosys_linux_test.go | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libcontainer/seccomp/patchbpf/enosys_linux_test.go b/libcontainer/seccomp/patchbpf/enosys_linux_test.go
index 5c79a56ba0..ee26a6a610 100644
--- a/libcontainer/seccomp/patchbpf/enosys_linux_test.go
+++ b/libcontainer/seccomp/patchbpf/enosys_linux_test.go
@@ -282,7 +282,7 @@ func TestEnosysStub_MultiArch(t *testing.T) {
}
}

-func TestPatchHugeSeccompFilterDoesNotBlock(t *testing.T) {
+func TestDisassembleHugeFilterDoesNotHang(t *testing.T) {
hugeFilter, err := libseccomp.NewFilter(libseccomp.ActAllow)
if err != nil {
t.Fatalf("failed to create seccomp filter: %v", err)
@@ -294,8 +294,10 @@ func TestPatchHugeSeccompFilterDoesNotBlock(t *testing.T) {
}
}

- config := fakeConfig(configs.Kill, []string{}, []string{"amd64"})
- PatchAndLoad(config, hugeFilter)
+ _, err = disassembleFilter(hugeFilter)
+ if err != nil {
+ t.Fatalf("failed to disassembleFilter: %v", err)
+ }

- // if we exit, we did not block
+ // if we exit, we did not hang
}
3 changes: 3 additions & 0 deletions packages/runc/runc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ License: Apache-2.0
URL: https://%{goimport}
Source0: https://%{goimport}/archive/%{commit}/%{gorepo}-%{commit}.tar.gz

Patch1001: 1001-runc-ensure-the-scratch-pipe-is-read-during-ExportBPF.patch
Patch1002: 1002-runc-make-test-specific-to-disassembleFilter-function.patch

BuildRequires: git
BuildRequires: %{_cross_os}glibc-devel
BuildRequires: %{_cross_os}libseccomp-devel
Expand Down

0 comments on commit 3eba03b

Please sign in to comment.