Merge pull request #17350 from giuseppe/allow-keep-id-for-root

libpod: allow userns=keep-id for root
This commit is contained in:
OpenShift Merge Robot
2023-02-03 15:19:30 +01:00
committed by GitHub
5 changed files with 36 additions and 45 deletions

View File

@ -28,7 +28,7 @@ Example: `containers:2147483647:2147483648`.
Podman allocates unique ranges of UIDs and GIDs from the `containers` subordinate user ids. The size of the ranges is based on the number of UIDs required in the image. The number of UIDs and GIDs can be overridden with the `size` option.
The rootless option `--userns=keep-id` uses all the subuids and subgids of the user. Using `--userns=auto` when starting new containers will not work as long as any containers exist that were started with `--userns=keep-id`.
The option `--userns=keep-id` uses all the subuids and subgids of the user. Using `--userns=auto` when starting new containers will not work as long as any containers exist that were started with `--userns=keep-id`.
Valid `auto` options:
@ -40,12 +40,12 @@ The rootless option `--userns=keep-id` uses all the subuids and subgids of the u
**host**: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default).
**keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is not allowed for containers created by the root user.
**keep-id**: creates a user namespace where the current user's UID:GID are mapped to the same values in the container. For containers created by root, the current mapping is created into a new user namespace.
Valid `keep-id` options:
- *uid*=UID: override the UID inside the container that will be used to map the current rootless user to.
- *gid*=GID: override the GID inside the container that will be used to map the current rootless user to.
- *uid*=UID: override the UID inside the container that will be used to map the current user to.
- *gid*=GID: override the GID inside the container that will be used to map the current user to.
**nomap**: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is not allowed for containers created by the root user.

View File

@ -1,7 +1,6 @@
package generate
import (
"errors"
"fmt"
"strings"
@ -194,9 +193,6 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.
// User
switch s.UserNS.NSMode {
case specgen.KeepID:
if !rootless.IsRootless() {
return nil, errors.New("keep-id is only supported in rootless mode")
}
opts, err := namespaces.UsernsMode(s.UserNS.String()).GetKeepIDOptions()
if err != nil {
return nil, err

View File

@ -113,13 +113,34 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
// GetKeepIDMapping returns the mappings and the user to use when keep-id is used
func GetKeepIDMapping(opts *namespaces.KeepIDUserNsOptions) (*stypes.IDMappingOptions, int, int, error) {
if !rootless.IsRootless() {
return nil, -1, -1, errors.New("keep-id is only supported in rootless mode")
}
options := stypes.IDMappingOptions{
HostUIDMapping: false,
HostGIDMapping: false,
}
if !rootless.IsRootless() {
uids, err := rootless.ReadMappingsProc("/proc/self/uid_map")
if err != nil {
return nil, 0, 0, err
}
gids, err := rootless.ReadMappingsProc("/proc/self/uid_map")
if err != nil {
return nil, 0, 0, err
}
options.UIDMap = uids
options.GIDMap = gids
uid, gid := 0, 0
if opts.UID != nil {
uid = int(*opts.UID)
}
if opts.GID != nil {
gid = int(*opts.GID)
}
return &options, uid, gid, nil
}
min := func(a, b int) int {
if a < b {
return a

View File

@ -128,11 +128,6 @@ var _ = Describe("Podman UserNS support", func() {
It("podman --userns=keep-id", func() {
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-u"})
session.WaitWithDefaultTimeout()
if !isRootless() {
Expect(session).Should(Exit(125))
Expect(session.ErrorToString()).To(ContainSubstring("keep-id is only supported in rootless mode"))
return
}
Expect(session).Should(Exit(0))
uid := fmt.Sprintf("%d", os.Geteuid())
@ -140,18 +135,12 @@ var _ = Describe("Podman UserNS support", func() {
session = podmanTest.Podman([]string{"run", "--userns=keep-id:uid=10,gid=12", "alpine", "sh", "-c", "echo $(id -u):$(id -g)"})
session.WaitWithDefaultTimeout()
if !isRootless() {
Expect(session).Should(Exit(125))
Expect(session.ErrorToString()).To(ContainSubstring("keep-id is only supported in rootless mode"))
return
}
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring("10:12"))
})
It("podman --userns=keep-id check passwd", func() {
SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-un"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@ -161,7 +150,6 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman --userns=keep-id root owns /usr", func() {
SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "stat", "-c%u", "/usr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@ -169,7 +157,6 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman --userns=keep-id --user root:root", func() {
SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "alpine", "id", "-u"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@ -177,7 +164,6 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman run --userns=keep-id can add users", func() {
SkipIfNotRootless("keep-id only works in rootless mode")
userName := os.Getenv("USER")
if userName == "" {
Skip("Can't complete test if no username available")
@ -403,8 +389,6 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman PODMAN_USERNS", func() {
SkipIfNotRootless("keep-id only works in rootless mode")
podmanUserns, podmanUserusSet := os.LookupEnv("PODMAN_USERNS")
os.Setenv("PODMAN_USERNS", "keep-id")
defer func() {

View File

@ -131,25 +131,15 @@ EOF
}
@test "podman userns=keep-id" {
if is_rootless; then
user=$(id -u)
run_podman run --rm --userns=keep-id $IMAGE id -u
is "${output}" "$user" "Container should run as the current user"
else
run_podman 125 run --rm --userns=keep-id $IMAGE id -u
is "${output}" "Error: keep-id is only supported in rootless mode" "Container should fail to start since keep-id is not supported in rootful mode"
fi
user=$(id -u)
run_podman run --rm --userns=keep-id $IMAGE id -u
is "${output}" "$user" "Container should run as the current user"
}
@test "podman userns=keep-id in a pod" {
if is_rootless; then
user=$(id -u)
run_podman pod create --userns keep-id
pid=$output
run_podman run --rm --pod $pid $IMAGE id -u
is "${output}" "$user" "Container should run as the current user"
else
run_podman 125 pod create --userns keep-id
is "${output}" 'Error:.*keep-id is only supported in rootless mode' "pod should fail to be created since keep-id is not supported in rootful mode"
fi
user=$(id -u)
run_podman pod create --userns keep-id
pid=$output
run_podman run --rm --pod $pid $IMAGE id -u
is "${output}" "$user" "Container should run as the current user"
}