Public bug reported:

After the kernel update from 7.0.0-38 to 7.0.0-42 (via unattended-
upgrades), processes inside Kubernetes (k3s/containerd) containers
confined by the containerd AppArmor profile can no longer signal each
other. PostgreSQL, which wakes its own processes with SIGURG, hangs:
connections stay in "authentication" forever until max_connections is
exhausted, an end-of-recovery checkpoint only starts after
checkpoint_timeout, and a smart shutdown never completes.

The audit log shows the signals being denied because the receiving
process carries a stacked label:

type=AVC msg=audit(1793391886.893:60882): apparmor="DENIED"
operation="signal" class="signal" profile="cri-containerd.apparmor.d"
pid=301516 comm="postgres" requested_mask="send" denied_mask="send"
signal=urg peer="cri-containerd.apparmor.d//&unconfined"

On 7.0.0-42 we saw 12,648 such denials over about 18 hours. On 7.0.0-38
and 7.0.0-39 there are none and all PostgreSQL processes carry the plain
label "cri-containerd.apparmor.d (enforce)".

Versions:
- Good: 7.0.0-38.38, 7.0.0-39.39
- Bad: 7.0.0-42.42 (7.0.0-41 was not published to the archive, so it could not 
be tested separately)
- Suspected change, in the 7.0.0-41 changelog: "apparmor: fix unconfined user 
namespace restriction forced stack"

Environment:
- Ubuntu 26.04.1 LTS, amd64, KVM virtual machine
- kernel.apparmor_restrict_unprivileged_userns = 1, 
kernel.unprivileged_userns_clone = 1
- apparmor 5.0.2-0ubuntu1~26.04.1
- k3s v1.36.5+k3s1, containerd v2.3.4-k3s1.36, runc 1.4.2
- CloudNativePG 1.30.1 with PostgreSQL 18.6 (the PostgreSQL container uses the 
default containerd AppArmor profile "cri-containerd.apparmor.d")

Steps to reproduce:
1. Boot 7.0.0-42 on a k3s node with AppArmor enabled.
2. Run PostgreSQL in a pod with the default containerd AppArmor profile (e.g. 
CloudNativePG).
3. Observe connections hanging in "authentication", "sorry, too many clients 
already", and the AVC denials above in /var/log/audit/audit.log.

Minimal reproduction without PostgreSQL: the attached latchtest.c blocks
SIGURG, reads it through a signalfd in an epoll set, and ping-pongs it
between two processes 20,000 times; a wake-up not arriving within one
second counts as lost. Run inside the container it loses wake-ups
whenever the processes carry the "//&unconfined" stacked label (as
processes started with "kubectl exec" do, also on 7.0.0-38/39); on the
host it never does.

Workaround: boot 7.0.0-39 (or 7.0.0-38). Running the PostgreSQL
container unconfined, or with a profile that also allows signals to peer
"cri-containerd.apparmor.d//&unconfined", would avoid the denials but
weakens confinement.

Note: apport is not installed on this hardened server, so apport-collect
cannot be run; the relevant information is included above.

** Affects: linux (Ubuntu)
     Importance: Undecided
         Status: New


** Tags: apparmor regression-update resolute

** Attachment added: "latchtest.c"
   
https://bugs.launchpad.net/bugs/2172640/+attachment/6013881/+files/latchtest.c

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172640

Title:
  Regression in 7.0.0-42: AppArmor forced "//&unconfined" stack on
  container processes blocks signals between them (PostgreSQL hangs)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2172640/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to