Skip to content

rootless userns=keep-id maps uid over overflowuid, effectively mapping host root user into the ns and breaking udev #27898

@chaserhkj

Description

@chaserhkj

Issue Description

Currently when running rootless with userns=keep-id, podman configures a uid map that maps over the entire 0-65535 uid map. since kernel only accepts overflowuid to be set to the same range as well, this means that overflowuid is always getting mapped into the userns, and thus host root which normally gets mapped to the overflowuid in rootless setups, will get an actual mapped user in the container. I am not sure about the security implications of this so someone may enlighten me. But the immediate impact is on relaxed container environments like toolbox or distrobox. This breaks the userns detection logic in libudev and makes it reject all uevents from host, thus breaking any hotplug-related apps from within the container. More details about this is in this comment

Steps to reproduce the issue

$ podman run -it --rm --userns=keep-id --net=host docker.io/archlinux/archlinux
-----------------------------------------------------------------------------------------------------
[hkj@hkj-desktop /]$ cat /proc/self/uid_map
         0          1       1000
      1000          0          1
      1001       1001     130073

overflowuid 65534 is mapped over in the third section

[hkj@hkj-desktop /]$ udevadm --debug monitor
monitor will print the received events for:
sd-device-monitor(n/a): The udev service seems not to be active, disabling the monitor.
sd-device-monitor(n/a): Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: Operation not permitted
sd-device-monitor(n/a): Failed to increase receive buffer size, ignoring: Operation not permitted
UDEV - the event which udev sends out after rule processing
sd-device-monitor(n/a): Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: Operation not permitted
sd-device-monitor(n/a): Failed to increase receive buffer size, ignoring: Operation not permitted
KERNEL - the kernel uevent

Triggering a uevent by plug/unplug some devices and we get:

sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.
sd-device-monitor(kernel): Sender uid=65534, message ignored.

libudev is ignoring all uevents from kernel, mainly because this logic in libudev is completely untriggered due to overflowuid being mapped over.

Describe the results you received

N.A. Results already interleaved in above section

Describe the results you expected

Ideally uid map should be something like

         0          1       1000
      1000          0          1
      1001       1001     65533
      65535     65535   65539

so that overflowuid is just skipped and libudev can properly take the uevents.

IMO there is really no benefit in mapping the overflowid, since if that uid is unmapped and anything tagged with it gets passed down into the userns, it would resolved into the same id anyways as unmapped id.

podman info output

host:
  arch: amd64
  buildahVersion: 1.41.5
  cgroupControllers:
  - cpuset
  - cpu
  - io
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-1:2.1.13-1
    path: /usr/bin/conmon
    version: 'conmon version 2.1.13, commit: 82de887596ed8ee6d9b2ee85e4f167f307bb569b'
  cpuUtilization:
    idlePercent: 88.18
    systemPercent: 1.77
    userPercent: 10.05
  cpus: 16
  databaseBackend: boltdb
  distribution:
    distribution: arch
    version: unknown
  emulatedArchitectures:
  - linux/arm
  - linux/arm64
  - linux/arm64be
  - linux/mips
  - linux/mips
  - linux/mips64
  - linux/ppc
  - linux/ppc64
  - linux/ppc64le
  - linux/riscv32
  - linux/riscv64
  - linux/s390x
  eventLogger: journald
  freeLocks: 2008
  hostname: hkj-desktop
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 131073
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 131073
  kernel: 6.16.4-zen1-1-zen
  linkmode: dynamic
  logDriver: journald
  memFree: 23539060736
  memTotal: 67327680512
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.16.0-1
      path: /usr/lib/podman/aardvark-dns
      version: aardvark-dns 1.16.0
    package: netavark-1.16.1-1
    path: /usr/lib/podman/netavark
    version: netavark 1.16.1
  ociRuntime:
    name: crun
    package: crun-1.25-1
    path: /usr/bin/crun
    version: |-
      crun version 1.25
      commit: d9a0adce065c7747ab88ea6ccc42b15a626e08e1
      rundir: /run/user/1000/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  pasta:
    executable: /usr/bin/pasta
    package: passt-2025_09_19.623dbf6-1
    version: |
      pasta 2025_09_19.623dbf6
      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: true
    path: /run/user/1000/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: /usr/bin/slirp4netns
    package: slirp4netns-1.3.3-1
    version: |-
      slirp4netns version 1.3.3
      commit: 944fa94090e1fd1312232cbc0e6b43585553d824
      libslirp: 4.9.1
      SLIRP_CONFIG_VERSION_MAX: 6
      libseccomp: 2.5.6
  swapFree: 204800
  swapTotal: 17179865088
  uptime: 604h 48m 52.00s (Approximately 25.17 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  localhost:5580:
    Blocked: false
    Insecure: true
    Location: localhost:5580
    MirrorByDigestOnly: false
    Mirrors: null
    Prefix: localhost:5580
    PullFromMirror: ""
  localhost:5581:
    Blocked: false
    Insecure: true
    Location: localhost:5581
    MirrorByDigestOnly: false
    Mirrors: null
    Prefix: localhost:5581
    PullFromMirror: ""
  search:
  - docker.io
store:
  configFile: /home/hkj/.config/containers/storage.conf
  containerStore:
    number: 12
    paused: 0
    running: 9
    stopped: 3
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/hkj/.local/share/containers/storage
  graphRootAllocated: 1614462976000
  graphRootUsed: 480570769408
  graphStatus:
    Backing Filesystem: zfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Supports shifting: "true"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 821
  runRoot: /run/user/1000/containers
  transientStore: false
  volumePath: /home/hkj/.local/share/containers/storage/volumes
version:
  APIVersion: 5.6.2
  Built: 1759398423
  BuiltTime: Thu Oct  2 05:47:03 2025
  GitCommit: 9dd5e1ed33830612bc200d7a13db00af6ab865a4
  GoVersion: go1.25.1 X:nodwarf5
  Os: linux
  OsArch: linux/amd64
  Version: 5.6.2

Podman in a container

No

Privileged Or Rootless

Rootless

Upstream Latest Release

Yes

Additional environment details

N.A.

Additional information

N.A.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions