Rootless `--userns=auto` fails when mapping UIDs >=1 without also mapping GIDs (OCI permission denied)
Closed this issue · 3 comments
Issue Description
When creating containers with rootless Podman with the option --userns=auto:uidmapping=1000:@2222:1
the creation fails with following error:
Error: crun: open `/home/user/.local/share/containers/storage/overlay/3057228a9bd8b1ce7235a70706b187cb0eaaf3a6e326cf5d30800600a187afb2/merged`: Permission denied: OCI permission denied
Please note that this issue does not appear when trying to map the CONTAINER_UID 0. E. g. following definition works: --userns=auto:uidmapping=0:@2222:1
.
This issue also does not occur when gidmapping is also specified., e. g.
--userns=auto:uidmapping=1000:@2222:1,gidmapping=1000:@2222:1
Steps to reproduce the issue
Steps to reproduce the issue
- Setup a unpriliged user to run podman containers. In my case I have a user with the name
user
and UID2222
. The specified user has following subordinate [GU]ID definition:user:100000:65536
. - Run a container with following command:
podman run \
--detach \
--rm \
--userns=auto:uidmapping=1000:@2222:1 \
docker.io/library/ubuntu:24.10 \
sleep infinity
Describe the results you received
The container creation failed with following error:
Error: crun: open `/home/user/.local/share/containers/storage/overlay/3057228a9bd8b1ce7235a70706b187cb0eaaf3a6e326cf5d30800600a187afb2/merged`: Permission denied: OCI permission denied
Describe the results you expected
I'd expect that the container is created with the specified uidmapping and automatically derives the gidmapping from it (as stated in the documentation).
The --userns=mode
section refers to the --uidmap
section. And there the following statement is made:
Usually, subordinated user and group ids are assigned simultaneously, and for any user the subordinated user ids match the subordinated group ids. For convenience, if only one of --uidmap or --gidmap is given, podman assumes the mapping refers to both UIDs and GIDs and applies the given mapping to both. [...]
podman info output
host:
arch: amd64
buildahVersion: 1.37.3
cgroupControllers:
- cpu
- memory
- pids
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon-1:2.1.12-1
path: /usr/bin/conmon
version: 'conmon version 2.1.12, commit: e8896631295ccb0bfdda4284f1751be19b483264'
cpuUtilization:
idlePercent: 99.91
systemPercent: 0.05
userPercent: 0.05
cpus: 6
databaseBackend: sqlite
distribution:
distribution: arch
version: unknown
eventLogger: journald
freeLocks: 2047
hostname: podman-test
idMappings:
gidmap:
- container_id: 0
host_id: 2222
size: 1
- container_id: 1
host_id: 100000
size: 65536
uidmap:
- container_id: 0
host_id: 2222
size: 1
- container_id: 1
host_id: 100000
size: 65536
kernel: 6.11.1-arch1-1
linkmode: dynamic
logDriver: journald
memFree: 7811739648
memTotal: 8330190848
networkBackend: netavark
networkBackendInfo:
backend: netavark
dns:
package: aardvark-dns-1.12.2-1
path: /usr/lib/podman/aardvark-dns
version: aardvark-dns 1.12.2
package: netavark-1.12.2-1
path: /usr/lib/podman/netavark
version: netavark 1.12.2
ociRuntime:
name: crun
package: crun-1.17-1
path: /usr/bin/crun
version: |-
crun version 1.17
commit: 000fa0d4eeed8938301f3bcf8206405315bc1017
rundir: /run/user/2222/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
os: linux
pasta:
executable: /usr/bin/pasta
package: passt-2024_09_06.6b38f07-1
version: |
pasta 2024_09_06.6b38f07
Copyright Red Hat
GNU General Public License, version 2 or later
<https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
remoteSocket:
exists: false
path: /run/user/2222/podman/podman.sock
rootlessNetworkCmd: pasta
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: true
seccompEnabled: true
seccompProfilePath: /etc/containers/seccomp.json
selinuxEnabled: false
serviceIsRemote: false
slirp4netns:
executable: ""
package: ""
version: ""
swapFree: 2147479552
swapTotal: 2147479552
uptime: 0h 52m 30.00s
variant: ""
plugins:
authorization: null
log:
- k8s-file
- none
- passthrough
- journald
network:
- bridge
- macvlan
- ipvlan
volume:
- local
registries: {}
store:
configFile: /home/user/.config/containers/storage.conf
containerStore:
number: 1
paused: 0
running: 1
stopped: 0
graphDriverName: overlay
graphOptions: {}
graphRoot: /home/user/.local/share/containers/storage
graphRootAllocated: 2040373248
graphRootUsed: 1863344128
graphStatus:
Backing Filesystem: extfs
Native Overlay Diff: "true"
Supports d_type: "true"
Supports shifting: "false"
Supports volatile: "true"
Using metacopy: "false"
imageCopyTmpDir: /var/tmp
imageStore:
number: 1
runRoot: /run/user/2222/containers
transientStore: false
volumePath: /home/user/.local/share/containers/storage/volumes
version:
APIVersion: 5.2.3
Built: 1727540747
BuiltTime: Sat Sep 28 18:25:47 2024
GitCommit: c5366a308e89edd9636b66faf79bd5cb18ed0905
GoVersion: go1.23.1
Os: linux
OsArch: linux/amd64
Version: 5.2.3
Podman in a container
No
Privileged Or Rootless
Rootless
Upstream Latest Release
Yes
Additional environment details
- KVM/QEMU guest managed by libvirt.
Additional information
I used following script for testing, maybe it eases the testing for you too:
#!/bin/bash
set -e
CONTAINER_NAME="ubuntu-test"
container_list=$(podman ps --filter "name=${CONTAINER_NAME}" --format "{{.Names}}")
if [ -n "${container_list}" ]; then
podman stop "${CONTAINER_NAME}"
else
echo "${CONTAINER_NAME} does not run"
fi
podman run \
--detach \
--rm \
--name "${CONTAINER_NAME}" \
--userns=auto:uidmapping=1000:@2222:1 \
docker.io/library/ubuntu:24.10 \
sleep infinity
# The ubuntu image has a predefined user 'ubuntu'.
# Start a process with that user to have both UIDs in the podman top overview.
podman exec --user ubuntu -d ubuntu-test sleep infinity
podman top ubuntu-test user,uid,huser,huid,args
Summery of the tested cases (I could not see any difference when the size
field was omitted):
Mode | --userns= parameter |
Does it work? |
---|---|---|
rootful | auto:uidmapping=0:2222 |
yes, root (container) = user (host). |
rootful | auto:uidmapping=1000:2222 |
yes, ubuntu (container) = user (host). |
rootless | auto:uidmapping=0:@2222 |
yes, root (container) = user (host). |
rootless | auto:uidmapping=1000:@2222 |
no, OCI permission denied. |
rootless | auto:uidmapping=1000:@2222,gidmapping=1000:@2222 |
yes, ubuntu (container) = user (host). |
podman top HUSER
display
I also noticed that the HUSER
field in podman top does not output the user name for rootless podman:
$ id
uid=2222(user) gid=2222(user) groups=2222(user)
$ podman top ubuntu-test user,uid,huser,huid,args
USER UID HUSER HUID COMMAND
root 0 2222 2222 sleep infinity
ubuntu 1000 100999 100999 sleep infinity
In rootful podman the user name is correctly displayed:
# id
uid=0(root) gid=0(root) groups=0(root)
# podman top ubuntu-test user,uid,huser,huid,args
USER UID HUSER HUID COMMAND
ubuntu 1000 user 2222 sleep infinity
root 0 2147483647 2147483647 sleep infinity
Is this works as intended or another issue?
I'd expect that the container is created with the specified uidmapping and automatically derives the gidmapping from it (as stated in the documentation).
@giuseppe this doesn't seem to be addressed by your PR.
the --uidmap
option and the flag for userns=auto
are two different things (even if having the same name...). The command should not fail and that is what my PR addresses.
Whether we need to change the semantic or not, that is a separate discussion. I am not sure we should, because the uidmappping=
allows to customize an individual mapping but leaves the auto
mappings untouched.