Bug 81 - pasta: selinux policy problems
Summary: pasta: selinux policy problems
Status: CONFIRMED
Alias: None
Product: passt
Classification: Unclassified
Component: pasta (show other bugs)
Version: unspecified
Hardware: All Linux
: Normal normal
Assignee: Stefano Brivio
URL:
Depends on:
Blocks:
 
Reported: 2024-03-01 16:55 UTC by Paul Holzinger
Modified: 2024-03-19 16:44 UTC (History)
2 users (show)

See Also:


Attachments

Description Paul Holzinger 2024-03-01 16:55:25 UTC
Running something simple like `pasta true` already yields several audit log denials

type=AVC msg=audit(1709311545.763:2330): avc:  denied  { name_bind } for  pid=53305 comm="pasta.avx2" src=67 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=system_u:object_r:dhcpd_port_t:s0 tclass=udp_socket permissive=0
type=AVC msg=audit(1709311545.763:2331): avc:  denied  { name_bind } for  pid=53305 comm="pasta.avx2" src=631 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=system_u:object_r:ipp_port_t:s0 tclass=udp_socket permissive=0
type=AVC msg=audit(1709311545.763:2332): avc:  denied  { name_bind } for  pid=53305 comm="pasta.avx2" src=1900 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=system_u:object_r:ssdp_port_t:s0 tclass=udp_socket permissive=0
type=AVC msg=audit(1709311545.763:2333): avc:  denied  { name_bind } for  pid=53305 comm="pasta.avx2" src=5353 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=system_u:object_r:howl_port_t:s0 tclass=udp_socket permissive=0
type=AVC msg=audit(1709311545.770:2334): avc:  denied  { name_bind } for  pid=53307 comm="pasta.avx2" src=631 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=system_u:object_r:ipp_port_t:s0 tclass=tcp_socket permissive=0



Doing something more like podman fails which tries to open a external netns also fails because of the selinux denials:
$ unshare -r
$ unshare -n sleep inf &
[1] 53421
$ pasta --config-net --netns  /proc/$!/ns/net
netns dir open: Permission denied, exiting


type=AVC msg=audit(1709311813.820:2370): avc:  denied  { setgid } for  pid=53887 comm="pasta.avx2" capability=6  scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns permissive=0
type=AVC msg=audit(1709311813.820:2371): avc:  denied  { setgid } for  pid=53887 comm="pasta.avx2" capability=6  scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns permissive=0
type=AVC msg=audit(1709311813.820:2372): avc:  denied  { setuid } for  pid=53887 comm="pasta.avx2" capability=7  scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns permissive=0
type=AVC msg=audit(1709311813.831:2373): avc:  denied  { read } for  pid=53887 comm="pasta.avx2" name="ns" dev="proc" ino=351971 scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=dir permissive=0


The only reason podman works today is because it runs as container_runtime_exec_t and does not transition to pasta_t.

I would assume that the default pasta_t policy should work and not block legitimate use cases.
Comment 1 Stefano Brivio 2024-03-04 10:53:33 UTC
(In reply to Paul Holzinger from comment #0)
> Running something simple like `pasta true` already yields several audit log
> denials
> 
> type=AVC msg=audit(1709311545.763:2330): avc:  denied  { name_bind } for 
> pid=53305 comm="pasta.avx2" src=67
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:dhcpd_port_t:s0 tclass=udp_socket permissive=0
> type=AVC msg=audit(1709311545.763:2331): avc:  denied  { name_bind } for 
> pid=53305 comm="pasta.avx2" src=631
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:ipp_port_t:s0 tclass=udp_socket permissive=0
> type=AVC msg=audit(1709311545.763:2332): avc:  denied  { name_bind } for 
> pid=53305 comm="pasta.avx2" src=1900
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:ssdp_port_t:s0 tclass=udp_socket permissive=0
> type=AVC msg=audit(1709311545.763:2333): avc:  denied  { name_bind } for 
> pid=53305 comm="pasta.avx2" src=5353
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:howl_port_t:s0 tclass=udp_socket permissive=0
> type=AVC msg=audit(1709311545.770:2334): avc:  denied  { name_bind } for 
> pid=53307 comm="pasta.avx2" src=631
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:ipp_port_t:s0 tclass=tcp_socket permissive=0
This is by design: my assumption was that we don't want, by default policy, to allow pasta to bind to every possible UDP or TCP port.

These are your open ports on the parent namespace, and, with -t auto / -u auto, which happens to be the default, pasta tries to bind these ports inside the namespace. I see three possible options:

- allow pasta to bind any TCP or UDP port, in both namespaces, target and parent

- the current behaviour: if the user wants to bind a specific port, they can edit their local SELinux policy (which is a configuration topic, somehow)

- find a way to tell SELinux to allow pasta to bind ports only inside the target namespace, which doesn't really add much to the security surface, but not in the parent namespace.

What would be your expectation?

> Doing something more like podman fails which tries to open a external netns
> also fails because of the selinux denials:
> $ unshare -r
> $ unshare -n sleep inf &
> [1] 53421
> $ pasta --config-net --netns  /proc/$!/ns/net
> netns dir open: Permission denied, exiting
Strange, this 


> 
> type=AVC msg=audit(1709311813.820:2370): avc:  denied  { setgid } for 
> pid=53887 comm="pasta.avx2" capability=6 
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> permissive=0
> type=AVC msg=audit(1709311813.820:2371): avc:  denied  { setgid } for 
> pid=53887 comm="pasta.avx2" capability=6 
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> permissive=0
> type=AVC msg=audit(1709311813.820:2372): avc:  denied  { setuid } for 
> pid=53887 comm="pasta.avx2" capability=7 
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> permissive=0
> type=AVC msg=audit(1709311813.831:2373): avc:  denied  { read } for 
> pid=53887 comm="pasta.avx2" name="ns" dev="proc" ino=351971
> scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=dir
> permissive=0
For some reason, I thought I fixed all this with commit 62059058cf24 ("selinux: Fix user namespace creation after breaking kernel change"), but now on Fedora 41 it looks like we need an additional:

  allow pasta_t self:cap_userns { setgid setuid };

...I'm not sure if this is due to a kernel change or to a base policy change in Fedora. Or maybe I just missed that, and we didn't exit when we failed to open the target namespace directory until recently.

> The only reason podman works today is because it runs as
> container_runtime_exec_t and does not transition to pasta_t.
Right, yes, and we should eventually implement the transition, with something similar to what we did for the integration with libvirt: pasta should export interfaces for any specific interaction with Podman -- and for AppArmor, we should use the existing abstraction (like it's already done for passt with libvirt).

> I would assume that the default pasta_t policy should work and not block
> legitimate use cases.
What's legitimate is a bit arbitrary -- I just created the profile and kept updating it with something that looked reasonable to me, but we surely don't want to push users to disable LSMs because policies are unusable.
Comment 2 Paul Holzinger 2024-03-04 14:20:09 UTC
(In reply to Stefano Brivio from comment #1)
> (In reply to Paul Holzinger from comment #0)
> > Running something simple like `pasta true` already yields several audit log
> > denials
> > 
> > type=AVC msg=audit(1709311545.763:2330): avc:  denied  { name_bind } for 
> > pid=53305 comm="pasta.avx2" src=67
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=system_u:object_r:dhcpd_port_t:s0 tclass=udp_socket permissive=0
> > type=AVC msg=audit(1709311545.763:2331): avc:  denied  { name_bind } for 
> > pid=53305 comm="pasta.avx2" src=631
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=system_u:object_r:ipp_port_t:s0 tclass=udp_socket permissive=0
> > type=AVC msg=audit(1709311545.763:2332): avc:  denied  { name_bind } for 
> > pid=53305 comm="pasta.avx2" src=1900
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=system_u:object_r:ssdp_port_t:s0 tclass=udp_socket permissive=0
> > type=AVC msg=audit(1709311545.763:2333): avc:  denied  { name_bind } for 
> > pid=53305 comm="pasta.avx2" src=5353
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=system_u:object_r:howl_port_t:s0 tclass=udp_socket permissive=0
> > type=AVC msg=audit(1709311545.770:2334): avc:  denied  { name_bind } for 
> > pid=53307 comm="pasta.avx2" src=631
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=system_u:object_r:ipp_port_t:s0 tclass=tcp_socket permissive=0
> This is by design: my assumption was that we don't want, by default policy,
> to allow pasta to bind to every possible UDP or TCP port.
> 
> These are your open ports on the parent namespace, and, with -t auto / -u
> auto, which happens to be the default, pasta tries to bind these ports
> inside the namespace. I see three possible options:
> 
> - allow pasta to bind any TCP or UDP port, in both namespaces, target and
> parent
> 
> - the current behaviour: if the user wants to bind a specific port, they can
> edit their local SELinux policy (which is a configuration topic, somehow)
> 
> - find a way to tell SELinux to allow pasta to bind ports only inside the
> target namespace, which doesn't really add much to the security surface, but
> not in the parent namespace.
> 
> What would be your expectation?

IMO it should allow to bind all ports. Of course this totally depends on what the
user intentions are. I can see that there is some value in not allowing all ports
but if we expect users to tweak the policy then they likely just turn of selinux.
Also AFAIK a rootless users cannot tweak the selinux policy at all so this would
somehow break our "rootless" story if they must change the policy to bind a
certain port assuming the blocked port is > 1023 otherwise they already need extra
configs to allow that.


> 
> > Doing something more like podman fails which tries to open a external netns
> > also fails because of the selinux denials:
> > $ unshare -r
> > $ unshare -n sleep inf &
> > [1] 53421
> > $ pasta --config-net --netns  /proc/$!/ns/net
> > netns dir open: Permission denied, exiting
> Strange, this 
> 
> 
> > 
> > type=AVC msg=audit(1709311813.820:2370): avc:  denied  { setgid } for 
> > pid=53887 comm="pasta.avx2" capability=6 
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> > permissive=0
> > type=AVC msg=audit(1709311813.820:2371): avc:  denied  { setgid } for 
> > pid=53887 comm="pasta.avx2" capability=6 
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> > permissive=0
> > type=AVC msg=audit(1709311813.820:2372): avc:  denied  { setuid } for 
> > pid=53887 comm="pasta.avx2" capability=7 
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023 tclass=cap_userns
> > permissive=0
> > type=AVC msg=audit(1709311813.831:2373): avc:  denied  { read } for 
> > pid=53887 comm="pasta.avx2" name="ns" dev="proc" ino=351971
> > scontext=unconfined_u:unconfined_r:pasta_t:s0-s0:c0.c1023
> > tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=dir
> > permissive=0
> For some reason, I thought I fixed all this with commit 62059058cf24
> ("selinux: Fix user namespace creation after breaking kernel change"), but
> now on Fedora 41 it looks like we need an additional:
> 
>   allow pasta_t self:cap_userns { setgid setuid };
> 
> ...I'm not sure if this is due to a kernel change or to a base policy change
> in Fedora. Or maybe I just missed that, and we didn't exit when we failed to
> open the target namespace directory until recently.

It failed already before that but I didn't really bother to much since it
worked with Podman's container_runtime_exec_t.

> 
> > The only reason podman works today is because it runs as
> > container_runtime_exec_t and does not transition to pasta_t.
> Right, yes, and we should eventually implement the transition, with
> something similar to what we did for the integration with libvirt: pasta
> should export interfaces for any specific interaction with Podman -- and for
> AppArmor, we should use the existing abstraction (like it's already done for
> passt with libvirt).

Agreed, which is why I opened this issue here with the current observed errors.
Note, I have no idea how selinux works or what this technically involves here.
All I can say X works or not if I turn on/off selinux.

> 
> > I would assume that the default pasta_t policy should work and not block
> > legitimate use cases.
> What's legitimate is a bit arbitrary -- I just created the profile and kept
> updating it with something that looked reasonable to me, but we surely don't
> want to push users to disable LSMs because policies are unusable.


Yes also agree, however if we want to make podman run pasta with pasta_t then
pasta_t needs to allow all podman use cases by default, i.e. bind all ports.
Switching would otherwise cause regressions for our users and result in a
frustrating user experience and possibly a high support workload for us as
people would start reporting issues as things no longer work.
Comment 3 Stefano Brivio 2024-03-04 15:38:22 UTC
(In reply to Paul Holzinger from comment #2)
> (In reply to Stefano Brivio from comment #1)
> > What would be your expectation?
> 
> IMO it should allow to bind all ports. Of course this totally depends on
> what the
> user intentions are. I can see that there is some value in not allowing all
> ports
> but if we expect users to tweak the policy then they likely just turn of
> selinux.
> Also AFAIK a rootless users cannot tweak the selinux policy at all so this
> would
> somehow break our "rootless" story if they must change the policy to bind a
> certain port assuming the blocked port is > 1023 otherwise they already need
> extra
> configs to allow that.
Also true I guess.

> > > The only reason podman works today is because it runs as
> > > container_runtime_exec_t and does not transition to pasta_t.
> > Right, yes, and we should eventually implement the transition, with
> > something similar to what we did for the integration with libvirt: pasta
> > should export interfaces for any specific interaction with Podman -- and for
> > AppArmor, we should use the existing abstraction (like it's already done for
> > passt with libvirt).
> 
> Agreed, which is why I opened this issue here with the current observed
> errors.
> Note, I have no idea how selinux works or what this technically involves
> here.
I can pretend I know how it works, and I already took care of this for libvirt, so I should probably go ahead with this, including changes in Podman. Let's use this bug to track that too.

Unless you know for sure that somebody familiar with Podman development wants to take care of the whole topic -- I'd be more than happy to delegate all this. Let me know, in case.

> All I can say X works or not if I turn on/off selinux.
> 
> > 
> > > I would assume that the default pasta_t policy should work and not block
> > > legitimate use cases.
> > What's legitimate is a bit arbitrary -- I just created the profile and kept
> > updating it with something that looked reasonable to me, but we surely don't
> > want to push users to disable LSMs because policies are unusable.
> 
> 
> Yes also agree, however if we want to make podman run pasta with pasta_t then
> pasta_t needs to allow all podman use cases by default, i.e. bind all ports.
There would actually be another solution for that: pasta's policy could export an interface for automatic port binding, that's then used by Podman to enable this. However:

> Switching would otherwise cause regressions for our users and result in a
> frustrating user experience and possibly a high support workload for us as
> people would start reporting issues as things no longer work.
...that would be a problem in this perspective, whenever we ask users to reproduce something with stand-alone pasta. Let's just go ahead and allow pasta to bind to any port.

Note You need to log in before you can comment on or make changes to this bug.