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