containers/podman

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

  1. Setup a unpriliged user to run podman containers. In my case I have a user with the name user and UID 2222. The specified user has following subordinate [GU]ID definition: user:100000:65536.
  2. 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?

opened a PR:

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.