Skip to content

runc run failure logging when the binary is on noexec fs #3520

@kolyshkin

Description

@kolyshkin

When runc run is called by podman, podman gathers run output, and if it contains "permission denied", exits with code of 126.

As demonstrated:

[kir@kir-rhat podman]$ ./bin/podman run --runtime=`pwd`/../../opencontainers/runc/runc busybox /etc
Error: /home/kir/go/src/github.com/containers/podman/../../opencontainers/runc/runc: runc create failed: unable to start container process: exec: "/etc": permission denied: OCI permission denied
[kir@kir-rhat podman]$ echo $?
126

Now, for some reason yet unknown to me, if the non-executable binary is on volume, runc fails to propagate the error back to podman.

Here's a repro with a slightly modified runc:

diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
index 17b05a55..2bed4846 100644
--- a/libcontainer/factory_linux.go
+++ b/libcontainer/factory_linux.go
@@ -175,10 +175,12 @@ func StartInitialization() (err error) {
                // We have an error during the initialization of the container's init,
                // send it back to the parent process in the form of an initError.
                if werr := writeSync(pipe, procError); werr != nil {
+                       fmt.Fprintln(os.Stderr, "init: write procError:", werr)
                        fmt.Fprintln(os.Stderr, err)
                        return
                }
                if werr := utils.WriteJSON(pipe, &initError{Message: err.Error()}); werr != nil {
+                       fmt.Fprintln(os.Stderr, "init: write initError:", werr)
                        fmt.Fprintln(os.Stderr, err)
                        return
                }

here is what happens normally:

[kir@kir-rhat podman]$ mkdir vol
[kir@kir-rhat podman]$ cat << EOL > ./vol/myscript
> #!/bin/sh
> echo hey you
> EOL
[kir@kir-rhat podman]$ chmod a+x ./vol/myscript 
[kir@kir-rhat podman]$ ./vol/myscript 
hey you
[kir@kir-rhat podman]$ ./bin/podman run --runtime=`pwd`/../../opencontainers/runc/runc --volume `pwd`/vol:/vol busybox /vol/myscript
hey you

Now, if we add noexec flag to the bind mount:

[kir@kir-rhat podman]$ ./bin/podman run --runtime=`pwd`/../../opencontainers/runc/runc --volume `pwd`/vol:/vol:noexec busybox /vol/myscript
init: write procError: writing syncT "procError": write pipe: file already closed
exec /vol/myscript: permission denied

This is some kind of a race upon exit. Can't figure out any more details at the moment¸will continue tomorrow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions