Hi Sam, Stefano, others,

(almost fully quoting because the Sam's original report Cc'ed
pa...@packages.debian.org, while I believe he meant to write to
pa...@packages.debian.org)

Sam Hartman (2025-03-11):
> Recently I started running into the following error shutting down
> containers with podman stop:
>
>       * rootless netns: kill network process: permission denied
>         This error is produced by
>         
> golang-github-containers-common/libnetwork/internal/rootlessnetns/netns_linux.go
>         in the cleanup function:
>               if err := n.cleanupRootlessNetns(); err != nil {
>               multiErr = multierror.Append(multiErr, wrapError("kill network 
> process", err))
>       }
>
> And that function effectively just finds and kills the pasta or
> slirp4netns process:
>       if err == nil {
>               // kill the slirp/pasta process so we do not leak it
>               err = unix.Kill(pid, unix.SIGTERM)
>               if err == unix.ESRCH {
>                       err = nil
>               }
>
> Looking at my kernel logs, I see that
> [  462.337636] audit: type=1400 audit(1741711021.533:118): apparmor="DENIED" 
> ope
> ration="signal" class="signal" profile="pasta" pid=4552 comm="exe" 
> requested_mas
> k="receive" denied_mask="receive" signal=term peer="podman"
> In other words, apparmor is preventing podman from cleaning up pasta.
>
> Podman is effectively supposed to be unconfined:
> Quoting /etc/apparmor.d/podman:
> # This profile allows everything and only exists to give the
> # application a name instead of having the label "unconfined"
>
> Although it turns out it's not really true that  podman can do anything
> because it turns out that the base abstraction specifically special
> cases the unconfined profile:
> (quoting /etc/apparmor.d/base)
>
>   # Allow unconfined processes to send us signals by default
>   signal (receive) peer=unconfined,
>
>   # Allow us to signal ourselves
>   signal peer=@{profile_name},
>
>   # Checking for PID existence is quite common so add it by default for now
>   signal (receive, send) set=("exists"),
>
>
> So, in other words, podman could send the signal if it were in the
> unconfined profile, but cannot because it has a profile at all.

Thank you Sam for educating me! I did not remember we had these rules
for unconfined processes.

> There's clearly a race condition involved somewhere. Some of my
> containers exhibit this behavior, but some do not.
> However, once it starts happening, it keeps happening, and it is common
> enough that it is breaking a lot of automation.
>
>
>
> On the apparmor side, I'd like to either see the bogus/empty podman
> profile removed   or to see signals from podman permitted by the pasta
> profile.

Thank you Sam for having gone to great lengths to investigate the
problem you were experiencing, up to the point where you could propose
these solutions.

I agree we should do 1 of those.

I would prefer we modify the pasta profile to allow signals
from podman, for 2 reasons:

 - It'll be necessary on Ubuntu, where removing the podman profile is
   not an option. It's not needed *yet* solely because the profile is
   not included in the Ubuntu package, which I'm guessing is a mistake
   that will be fixed at some point
   (https://bugs.launchpad.net/ubuntu/+source/passt/+bug/2077158).
   So we can as well fix this proactively. And the fix should probably
   be upstreamed.

 - It's 1 tiny but still useful step towards being able to some day
   stop accepting signals from unconfined processes.

Stefano, what do you think?

I believe this (untested) rule should do the job:

  signal (receive) peer=podman,

If we don't do that, then I'm fine with removing the podman profile,
which has limited value anyway in the context of Debian.

Cheers,
-- 
intrigeri

Reply via email to