summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Antonio Osorio Robles <jaosorior@redhat.com>2021-01-12 15:54:32 +0200
committerJuan Antonio Osorio Robles <jaosorior@redhat.com>2021-01-12 16:10:17 +0200
commit020abbfeab3b3f3bc3b82edf1b9374b90d79ae91 (patch)
tree83cdea752a30c8de623a6fe3798ca59db0525be2
parent64b86d004ebd7db0b2bc352475505050be0f8591 (diff)
downloadpodman-020abbfeab3b3f3bc3b82edf1b9374b90d79ae91.tar.gz
podman-020abbfeab3b3f3bc3b82edf1b9374b90d79ae91.tar.bz2
podman-020abbfeab3b3f3bc3b82edf1b9374b90d79ae91.zip
Expose security attribute errors with their own messages
This creates error objects for runtime errors that might come from the runtime. Thus, indicating to users that the place to debug should be in the security attributes of the container. When creating a container with a SELinux label that doesn't exist, we get a fairly cryptic error message: ``` $ podman run --security-opt label=type:my_container.process -it fedora bash Error: OCI runtime error: write file `/proc/thread-self/attr/exec`: Invalid argument ``` This instead handles any errors coming from LSM's `/proc` API and enhances the error message with a relevant indicator that it's related to the container's security attributes. A sample run looks as follows: ``` $ bin/podman run --security-opt label=type:my_container.process -it fedora bash Error: `/proc/thread-self/attr/exec`: OCI runtime error: unable to assign security attribute ``` With `debug` log level enabled it would be: ``` Error: write file `/proc/thread-self/attr/exec`: Invalid argument: OCI runtime error: unable to assign security attribute ``` Note that these errors wrap ErrOCIRuntime, so it's still possible to to compare these errors with `errors.Is/errors.As`. One advantage of this approach is that we could start handling these errors in a more efficient manner in the future. e.g. If a SELinux label doesn't exist (yet), we could retry until it becomes available. Signed-off-by: Juan Antonio Osorio Robles <jaosorior@redhat.com>
-rw-r--r--libpod/define/errors.go13
-rw-r--r--libpod/oci_util.go12
2 files changed, 25 insertions, 0 deletions
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index b96d36429..568f8e88d 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -2,6 +2,7 @@ package define
import (
"errors"
+ "fmt"
)
var (
@@ -181,4 +182,16 @@ var (
// ErrNoNetwork indicates that a container has no net namespace, like network=none
ErrNoNetwork = errors.New("container has no network namespace")
+
+ // ErrSetSecurityAttribute indicates that a request to set a container's security attribute
+ // was not possible.
+ ErrSetSecurityAttribute = fmt.Errorf("%w: unable to assign security attribute", ErrOCIRuntime)
+
+ // ErrGetSecurityAttribute indicates that a request to get a container's security attribute
+ // was not possible.
+ ErrGetSecurityAttribute = fmt.Errorf("%w: unable to get security attribute", ErrOCIRuntime)
+
+ // ErrSecurityAttribute indicates that an error processing security attributes
+ // for the container
+ ErrSecurityAttribute = fmt.Errorf("%w: unable to process security attribute", ErrOCIRuntime)
)
diff --git a/libpod/oci_util.go b/libpod/oci_util.go
index 2ba85c4b3..d40cf13bd 100644
--- a/libpod/oci_util.go
+++ b/libpod/oci_util.go
@@ -126,5 +126,17 @@ func getOCIRuntimeError(runtimeMsg string) error {
}
return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(errStr, "\n"))
}
+ if match := regexp.MustCompile("`/proc/[a-z0-9-].+/attr.*`").FindString(runtimeMsg); match != "" {
+ errStr := match
+ if includeFullOutput {
+ errStr = runtimeMsg
+ }
+ if strings.HasSuffix(match, "/exec`") {
+ return errors.Wrapf(define.ErrSetSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ } else if strings.HasSuffix(match, "/current`") {
+ return errors.Wrapf(define.ErrGetSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ }
+ return errors.Wrapf(define.ErrSecurityAttribute, "%s", strings.Trim(errStr, "\n"))
+ }
return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n"))
}