Skip to content

Commit

Permalink
unshare: improve rootless detection
Browse files Browse the repository at this point in the history
in addition to check the UID of the user that launched the command,
also check whether the process has CAP_SYS_ADMIN (in the same way as
podman/pkg/rootless does) and also check that the current user
namespace has all the IDs available.

Closes: #1311

After this change, podman/pkg/rootless can use the function directly
instead of defining another version with similar functionalities.

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Aug 24, 2022
1 parent d3f1078 commit 966eeb8
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions pkg/unshare/unshare_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"os/signal"
Expand Down Expand Up @@ -387,10 +388,42 @@ const (
UsernsEnvName = "_CONTAINERS_USERNS_CONFIGURED"
)

// hasFullUsersMappings checks whether the current user namespace has all the IDs mapped.
// current user namespace
func hasFullUsersMappings() (bool, error) {
content, err := ioutil.ReadFile("/proc/self/uid_map")
if err != nil {
return false, err
}
// Both runc and crun check whether the current process is in a user namespace
// by looking up 4294967295 in /proc/self/uid_map. If the mappings would be
// copied as they are, the check in the OCI runtimes would fail. So just split
// it in two different ranges.
return bytes.Contains(content, []byte("4294967295")), nil
}

// IsRootless tells us if we are running in rootless mode
func IsRootless() bool {
isRootlessOnce.Do(func() {
isRootless = getRootlessUID() != 0 || getenv(UsernsEnvName) != ""
if !isRootless {
hasCapSysAdmin, err := HasCapSysAdmin()
if err != nil {
logrus.Warnf("Failed to read CAP_SYS_ADMIN presence for the current process")
}
if err == nil && !hasCapSysAdmin {
isRootless = true
}
}
if !isRootless {
hasMappings, err := hasFullUsersMappings()
if err != nil {
logrus.Warnf("Failed to read current user namespace mappings")
}
if err == nil && !hasMappings {
isRootless = true
}
}
})
return isRootless
}
Expand Down

0 comments on commit 966eeb8

Please sign in to comment.