Hello community, here is the log from the commit of package docker-runc for openSUSE:Factory checked in at 2018-06-22 13:16:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/docker-runc (Old) and /work/SRC/openSUSE:Factory/.docker-runc.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "docker-runc" Fri Jun 22 13:16:11 2018 rev:10 rq:617458 version:1.0.0rc4+gitr3338_3f2f8b84a77f Changes: -------- --- /work/SRC/openSUSE:Factory/docker-runc/docker-runc.changes 2018-06-08 23:09:45.016446735 +0200 +++ /work/SRC/openSUSE:Factory/.docker-runc.new/docker-runc.changes 2018-06-22 13:16:16.233063592 +0200 @@ -1,0 +2,12 @@ +Thu Jun 7 06:42:21 UTC 2018 - asa...@suse.com + +- Backport of https://github.com/opencontainers/runc/pull/1698 to help fix + bsc#1094680, which is caused by the race described in the upstream issue. + * bsc1094680-0001-Avoid-race-when-opening-exec-fifo.patch + +------------------------------------------------------------------- +Tue Jun 5 08:46:09 UTC 2018 - dcass...@suse.com + +- Make use of %license macro + +------------------------------------------------------------------- New: ---- bsc1094680-0001-Avoid-race-when-opening-exec-fifo.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ docker-runc.spec ++++++ --- /var/tmp/diff_new_pack.ugNCnR/_old 2018-06-22 13:16:16.989035560 +0200 +++ /var/tmp/diff_new_pack.ugNCnR/_new 2018-06-22 13:16:16.993035411 +0200 @@ -54,6 +54,8 @@ Source: %{name}-git.%{git_version}.tar.xz # SUSE-FIX-UPSTREAM: Backport of https://github.com/opencontainers/runc/pull/1555. bsc#1053532 Patch100: bsc1053532-0001-makefile-drop-usage-of-install.patch +# SUSE-FIX-UPSTREAM: Backport of https://github.com/opencontainers/runc/pull/1698. bsc#1094680 +Patch101: bsc1094680-0001-Avoid-race-when-opening-exec-fifo.patch BuildRequires: fdupes BuildRequires: go-go-md2man BuildRequires: libapparmor-devel @@ -96,6 +98,8 @@ %setup -q -n %{name}-git.%{git_version} # bsc#1053532 %patch100 -p1 +# bsc#1094680 +%patch101 -p1 %build # Do not use symlinks. If you want to run the unit tests for this package at @@ -159,7 +163,8 @@ %files %defattr(-,root,root) -%doc README.md LICENSE +%doc README.md +%license LICENSE %{_sbindir}/docker-runc %{_mandir}/man8/docker-runc*.8.gz ++++++ bsc1094680-0001-Avoid-race-when-opening-exec-fifo.patch ++++++ >From 331f9819f515be7d8a1bdd7a68d9dac0c87f3015 Mon Sep 17 00:00:00 2001 From: Will Martin <wmar...@pivotal.io> Date: Mon, 22 Jan 2018 17:03:02 +0000 Subject: [PATCH] Avoid race when opening exec fifo When starting a container with `runc start` or `runc run`, the stub process (runc[2:INIT]) opens a fifo for writing. Its parent runc process will open the same fifo for reading. In this way, they synchronize. If the stub process exits at the wrong time, the parent runc process will block forever. This can happen when racing 2 runc operations against each other: `runc run/start`, and `runc delete`. It could also happen for other reasons, e.g. the kernel's OOM killer may select the stub process. This commit resolves this race by racing the opening of the exec fifo from the runc parent process against the stub process exiting. If the stub process exits before we open the fifo, we return an error. Another solution is to wait on the stub process. However, it seems it would require more refactoring to avoid calling wait multiple times on the same process, which is an error. SUSE-Bugs: bsc#1094680 Signed-off-by: Craig Furman <cfur...@pivotal.io> Signed-off-by: Aleksa Sarai <asa...@suse.de> --- libcontainer/container_linux.go | 70 +++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index d7e7516e5493..1ffbff70ba5a 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -5,6 +5,7 @@ package libcontainer import ( "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -236,20 +237,71 @@ func (c *linuxContainer) Exec() error { func (c *linuxContainer) exec() error { path := filepath.Join(c.root, execFifoFilename) - f, err := os.OpenFile(path, os.O_RDONLY, 0) - if err != nil { - return newSystemErrorWithCause(err, "open exec fifo for reading") + + fifoOpen := make(chan struct{}) + select { + case <-awaitProcessExit(c.initProcess.pid(), fifoOpen): + return errors.New("container process is already dead") + case result := <-awaitFifoOpen(path): + close(fifoOpen) + if result.err != nil { + return result.err + } + f := result.file + defer f.Close() + if err := readFromExecFifo(f); err != nil { + return err + } + return os.Remove(path) } - defer f.Close() - data, err := ioutil.ReadAll(f) +} + +func readFromExecFifo(execFifo io.Reader) error { + data, err := ioutil.ReadAll(execFifo) if err != nil { return err } - if len(data) > 0 { - os.Remove(path) - return nil + if len(data) <= 0 { + return fmt.Errorf("cannot start an already running container") } - return fmt.Errorf("cannot start an already running container") + return nil +} + +func awaitProcessExit(pid int, exit <-chan struct{}) <-chan struct{} { + isDead := make(chan struct{}) + go func() { + for { + select { + case <-exit: + return + case <-time.After(time.Millisecond * 100): + stat, err := system.Stat(pid) + if err != nil || stat.State == system.Zombie { + close(isDead) + return + } + } + } + }() + return isDead +} + +func awaitFifoOpen(path string) <-chan openResult { + fifoOpened := make(chan openResult) + go func() { + f, err := os.OpenFile(path, os.O_RDONLY, 0) + if err != nil { + fifoOpened <- openResult{err: newSystemErrorWithCause(err, "open exec fifo for reading")} + return + } + fifoOpened <- openResult{file: f} + }() + return fifoOpened +} + +type openResult struct { + file *os.File + err error } func (c *linuxContainer) start(process *Process, isInit bool) error { -- 2.16.3