All of lore.kernel.org
 help / color / mirror / Atom feed
* DBus Permissions
@ 2025-11-06 19:57 Rahul Sandhu
  2025-11-07 13:28 ` Stephen Smalley
  0 siblings, 1 reply; 4+ messages in thread
From: Rahul Sandhu @ 2025-11-06 19:57 UTC (permalink / raw)
  To: selinux; +Cc: dominick.grift, lautrbach, cgzones

I've been looking into SELinux support for filtering DBus permissions
lately. Right now, we have a few things of note from the dbus class:

(class dbus (acquire_svc send_msg))

1. acquire_svc. This is useful for:
   Allowing contexts to own names on the bus. We have numerous names
   that exist on the bus that are effectively trusted: applications
   need to be able to trust that the owner of a name is the intended
   target. An example of this would be org.freedesktop.PolicyKit1 and
   polkit: applications check if unprivileged subjects are allowed to
   perform privileged operations using this DBus API. We can make use of
   acquire_svc to ensure that only e.g. polkit.subj may own that name.

2. send_msg. This is useful for ensuring that subjects may only speak
   to their intended targets.

However, this has some serious limitations. For one, many names on the
bus provide *both* unprivileged and privileged interfaces. An example
of this is org.freedesktop.systemd1, the systemd api. It has various
actions that aren't all that privileged (for example GetUnit) as well
as actions that are highly privileged (such as StartUnit). A bug has
been filed[1] such that any service capable of speaking to systemd over
dbus can effectively escape its sandboxing (systemd's sandboxing, not
selinux confinement)! It can simply start a transient unit using dbus
without the same restrictions applied to the unit.

In the case of systemd however, the situation is actually *much* better
than other cases: systemd is actually SELinux aware and is an object
manager, which means we at least have some control over what happens.
However, dbus is a pretty fundermental IPC primative for desktop Linux.
Plenty of things that aren't object managers nor SELinux aware provide
privileged and unprivileged interfaces on the same bus name. One of the
main advantages of brokering is the ability to perform various checks
without the server needing to implement them.

Hence, I propose extending what we can do with DBus to allow us to be
much more granular with it. Other LSMs and IPC systems already have
access control similar to this:

1. Android's binder supports service names being labelled[2]. This is
   slightly different to the case of DBus here with binder being part
   of the kernel, however the core concept could still apply as we may
   simply provide dropins to extend the functionality of dbus config
   to label names, and extend the dbus class. This would provide back-
   wards compatability. It's also somewhat limited however because of
   the DBus IPC design.

2. AppArmor has a much more rich access control setup for DBus. It does
   not require installing DBus policy files, and supports performing
   filtering based on the bus type, the path on the bus, the interface,
   and the member. It also supports representing this all in policy[3].
   This is in my opinion a much cleaner approach than requiring us to
   have loads of labels for each possible member and interface. However,
   I don't really have any idea as to how we this could represented in
   policy. Maybe something using xperms? But I'm a bit lost as to how
   an xperm set could be mapped to it.

[1] https://github.com/systemd/systemd/issues/8846
[2] https://source.android.com/docs/core/architecture/hidl/binder-ipc#names
[3] https://man.archlinux.org/man/apparmor.d.5.en#DBus_rules

Thoughts/suggestions?
Rahul

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: DBus Permissions
  2025-11-06 19:57 DBus Permissions Rahul Sandhu
@ 2025-11-07 13:28 ` Stephen Smalley
  2025-11-07 13:56   ` Stephen Smalley
  2025-11-07 15:28   ` Rahul Sandhu
  0 siblings, 2 replies; 4+ messages in thread
From: Stephen Smalley @ 2025-11-07 13:28 UTC (permalink / raw)
  To: Rahul Sandhu; +Cc: selinux, dominick.grift, lautrbach, cgzones

On Thu, Nov 6, 2025 at 2:58 PM Rahul Sandhu <nvraxn@gmail.com> wrote:
>
> I've been looking into SELinux support for filtering DBus permissions
> lately. Right now, we have a few things of note from the dbus class:
>
> (class dbus (acquire_svc send_msg))
>
> 1. acquire_svc. This is useful for:
>    Allowing contexts to own names on the bus. We have numerous names
>    that exist on the bus that are effectively trusted: applications
>    need to be able to trust that the owner of a name is the intended
>    target. An example of this would be org.freedesktop.PolicyKit1 and
>    polkit: applications check if unprivileged subjects are allowed to
>    perform privileged operations using this DBus API. We can make use of
>    acquire_svc to ensure that only e.g. polkit.subj may own that name.
>
> 2. send_msg. This is useful for ensuring that subjects may only speak
>    to their intended targets.
>
> However, this has some serious limitations. For one, many names on the
> bus provide *both* unprivileged and privileged interfaces. An example
> of this is org.freedesktop.systemd1, the systemd api. It has various
> actions that aren't all that privileged (for example GetUnit) as well
> as actions that are highly privileged (such as StartUnit). A bug has
> been filed[1] such that any service capable of speaking to systemd over
> dbus can effectively escape its sandboxing (systemd's sandboxing, not
> selinux confinement)! It can simply start a transient unit using dbus
> without the same restrictions applied to the unit.
>
> In the case of systemd however, the situation is actually *much* better
> than other cases: systemd is actually SELinux aware and is an object
> manager, which means we at least have some control over what happens.
> However, dbus is a pretty fundermental IPC primative for desktop Linux.
> Plenty of things that aren't object managers nor SELinux aware provide
> privileged and unprivileged interfaces on the same bus name. One of the
> main advantages of brokering is the ability to perform various checks
> without the server needing to implement them.
>
> Hence, I propose extending what we can do with DBus to allow us to be
> much more granular with it. Other LSMs and IPC systems already have
> access control similar to this:
>
> 1. Android's binder supports service names being labelled[2]. This is
>    slightly different to the case of DBus here with binder being part
>    of the kernel, however the core concept could still apply as we may
>    simply provide dropins to extend the functionality of dbus config
>    to label names, and extend the dbus class. This would provide back-
>    wards compatability. It's also somewhat limited however because of
>    the DBus IPC design.
>
> 2. AppArmor has a much more rich access control setup for DBus. It does
>    not require installing DBus policy files, and supports performing
>    filtering based on the bus type, the path on the bus, the interface,
>    and the member. It also supports representing this all in policy[3].
>    This is in my opinion a much cleaner approach than requiring us to
>    have loads of labels for each possible member and interface. However,
>    I don't really have any idea as to how we this could represented in
>    policy. Maybe something using xperms? But I'm a bit lost as to how
>    an xperm set could be mapped to it.

In the olden days before SELinux, when we were working with the CMU
Mach microkernel and its IPC system [1],
we auto-generated access vector definitions (permission names) from
the Mach Interface Generation (MIG) files,
and each access vector had a general portion with common permissions
and then a service-specific portion with the
generated permissions. As long as you have no more than 32 interfaces
per interface, you can fit that in an access vector
without xperms; else you could use xperms for that purpose. WRT
xperms, it's just a matter of mapping each interface to
an integer index which likely already happens and then using that to
generate a mapping for policy writers to use.

[1] https://www-old.cs.utah.edu/flux/fluke/html/dtos/HTML/dtos.html

> [1] https://github.com/systemd/systemd/issues/8846
> [2] https://source.android.com/docs/core/architecture/hidl/binder-ipc#names
> [3] https://man.archlinux.org/man/apparmor.d.5.en#DBus_rules
>
> Thoughts/suggestions?
> Rahul

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: DBus Permissions
  2025-11-07 13:28 ` Stephen Smalley
@ 2025-11-07 13:56   ` Stephen Smalley
  2025-11-07 15:28   ` Rahul Sandhu
  1 sibling, 0 replies; 4+ messages in thread
From: Stephen Smalley @ 2025-11-07 13:56 UTC (permalink / raw)
  To: Rahul Sandhu; +Cc: selinux, dominick.grift, lautrbach, cgzones

On Fri, Nov 7, 2025 at 8:28 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Thu, Nov 6, 2025 at 2:58 PM Rahul Sandhu <nvraxn@gmail.com> wrote:
> >
> > I've been looking into SELinux support for filtering DBus permissions
> > lately. Right now, we have a few things of note from the dbus class:
> >
> > (class dbus (acquire_svc send_msg))
> >
> > 1. acquire_svc. This is useful for:
> >    Allowing contexts to own names on the bus. We have numerous names
> >    that exist on the bus that are effectively trusted: applications
> >    need to be able to trust that the owner of a name is the intended
> >    target. An example of this would be org.freedesktop.PolicyKit1 and
> >    polkit: applications check if unprivileged subjects are allowed to
> >    perform privileged operations using this DBus API. We can make use of
> >    acquire_svc to ensure that only e.g. polkit.subj may own that name.
> >
> > 2. send_msg. This is useful for ensuring that subjects may only speak
> >    to their intended targets.
> >
> > However, this has some serious limitations. For one, many names on the
> > bus provide *both* unprivileged and privileged interfaces. An example
> > of this is org.freedesktop.systemd1, the systemd api. It has various
> > actions that aren't all that privileged (for example GetUnit) as well
> > as actions that are highly privileged (such as StartUnit). A bug has
> > been filed[1] such that any service capable of speaking to systemd over
> > dbus can effectively escape its sandboxing (systemd's sandboxing, not
> > selinux confinement)! It can simply start a transient unit using dbus
> > without the same restrictions applied to the unit.
> >
> > In the case of systemd however, the situation is actually *much* better
> > than other cases: systemd is actually SELinux aware and is an object
> > manager, which means we at least have some control over what happens.
> > However, dbus is a pretty fundermental IPC primative for desktop Linux.
> > Plenty of things that aren't object managers nor SELinux aware provide
> > privileged and unprivileged interfaces on the same bus name. One of the
> > main advantages of brokering is the ability to perform various checks
> > without the server needing to implement them.
> >
> > Hence, I propose extending what we can do with DBus to allow us to be
> > much more granular with it. Other LSMs and IPC systems already have
> > access control similar to this:
> >
> > 1. Android's binder supports service names being labelled[2]. This is
> >    slightly different to the case of DBus here with binder being part
> >    of the kernel, however the core concept could still apply as we may
> >    simply provide dropins to extend the functionality of dbus config
> >    to label names, and extend the dbus class. This would provide back-
> >    wards compatability. It's also somewhat limited however because of
> >    the DBus IPC design.
> >
> > 2. AppArmor has a much more rich access control setup for DBus. It does
> >    not require installing DBus policy files, and supports performing
> >    filtering based on the bus type, the path on the bus, the interface,
> >    and the member. It also supports representing this all in policy[3].
> >    This is in my opinion a much cleaner approach than requiring us to
> >    have loads of labels for each possible member and interface. However,
> >    I don't really have any idea as to how we this could represented in
> >    policy. Maybe something using xperms? But I'm a bit lost as to how
> >    an xperm set could be mapped to it.
>
> In the olden days before SELinux, when we were working with the CMU
> Mach microkernel and its IPC system [1],
> we auto-generated access vector definitions (permission names) from
> the Mach Interface Generation (MIG) files,
> and each access vector had a general portion with common permissions
> and then a service-specific portion with the
> generated permissions. As long as you have no more than 32 interfaces
> per interface, you can fit that in an access vector
> without xperms; else you could use xperms for that purpose. WRT
> xperms, it's just a matter of mapping each interface to
> an integer index which likely already happens and then using that to
> generate a mapping for policy writers to use.

I should note however that we largely moved away from that model for
the successors to DTMach/DTOS, splitting out separate class/permission
definitions and responsibility to the individual object managers.
Checking the "service" permissions in the auto-generated IPC wrappers
or subsystem has its own set of limitations, e.g. the object manager
will not yet have looked up and potentially locked the underlying
object in question.

>
> [1] https://www-old.cs.utah.edu/flux/fluke/html/dtos/HTML/dtos.html
>
> > [1] https://github.com/systemd/systemd/issues/8846
> > [2] https://source.android.com/docs/core/architecture/hidl/binder-ipc#names
> > [3] https://man.archlinux.org/man/apparmor.d.5.en#DBus_rules
> >
> > Thoughts/suggestions?
> > Rahul

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: DBus Permissions
  2025-11-07 13:28 ` Stephen Smalley
  2025-11-07 13:56   ` Stephen Smalley
@ 2025-11-07 15:28   ` Rahul Sandhu
  1 sibling, 0 replies; 4+ messages in thread
From: Rahul Sandhu @ 2025-11-07 15:28 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, dominick.grift, lautrbach, cgzones

On Fri Nov 7, 2025 at 1:28 PM GMT, Stephen Smalley wrote:
> On Thu, Nov 6, 2025 at 2:58 PM Rahul Sandhu <nvraxn@gmail.com> wrote:
>>
>> I've been looking into SELinux support for filtering DBus permissions
>> lately. Right now, we have a few things of note from the dbus class:
>>
>> (class dbus (acquire_svc send_msg))
>>
>> 1. acquire_svc. This is useful for:
>>    Allowing contexts to own names on the bus. We have numerous names
>>    that exist on the bus that are effectively trusted: applications
>>    need to be able to trust that the owner of a name is the intended
>>    target. An example of this would be org.freedesktop.PolicyKit1 and
>>    polkit: applications check if unprivileged subjects are allowed to
>>    perform privileged operations using this DBus API. We can make use of
>>    acquire_svc to ensure that only e.g. polkit.subj may own that name.
>>
>> 2. send_msg. This is useful for ensuring that subjects may only speak
>>    to their intended targets.
>>
>> However, this has some serious limitations. For one, many names on the
>> bus provide *both* unprivileged and privileged interfaces. An example
>> of this is org.freedesktop.systemd1, the systemd api. It has various
>> actions that aren't all that privileged (for example GetUnit) as well
>> as actions that are highly privileged (such as StartUnit). A bug has
>> been filed[1] such that any service capable of speaking to systemd over
>> dbus can effectively escape its sandboxing (systemd's sandboxing, not
>> selinux confinement)! It can simply start a transient unit using dbus
>> without the same restrictions applied to the unit.
>>
>> In the case of systemd however, the situation is actually *much* better
>> than other cases: systemd is actually SELinux aware and is an object
>> manager, which means we at least have some control over what happens.
>> However, dbus is a pretty fundermental IPC primative for desktop Linux.
>> Plenty of things that aren't object managers nor SELinux aware provide
>> privileged and unprivileged interfaces on the same bus name. One of the
>> main advantages of brokering is the ability to perform various checks
>> without the server needing to implement them.
>>
>> Hence, I propose extending what we can do with DBus to allow us to be
>> much more granular with it. Other LSMs and IPC systems already have
>> access control similar to this:
>>
>> 1. Android's binder supports service names being labelled[2]. This is
>>    slightly different to the case of DBus here with binder being part
>>    of the kernel, however the core concept could still apply as we may
>>    simply provide dropins to extend the functionality of dbus config
>>    to label names, and extend the dbus class. This would provide back-
>>    wards compatability. It's also somewhat limited however because of
>>    the DBus IPC design.
>>
>> 2. AppArmor has a much more rich access control setup for DBus. It does
>>    not require installing DBus policy files, and supports performing
>>    filtering based on the bus type, the path on the bus, the interface,
>>    and the member. It also supports representing this all in policy[3].
>>    This is in my opinion a much cleaner approach than requiring us to
>>    have loads of labels for each possible member and interface. However,
>>    I don't really have any idea as to how we this could represented in
>>    policy. Maybe something using xperms? But I'm a bit lost as to how
>>    an xperm set could be mapped to it.
>
> In the olden days before SELinux, when we were working with the CMU
> Mach microkernel and its IPC system [1],
> we auto-generated access vector definitions (permission names) from
> the Mach Interface Generation (MIG) files,
> and each access vector had a general portion with common permissions
> and then a service-specific portion with the
> generated permissions. As long as you have no more than 32 interfaces
> per interface, you can fit that in an access vector
> without xperms; else you could use xperms for that purpose. WRT
> xperms, it's just a matter of mapping each interface to
> an integer index which likely already happens and then using that to
> generate a mapping for policy writers to use.

That might very well be a good feasible option actually. I also took a
look at what actually needs labelling and came up with another idea too
to label each member (effectively the IPC endpoints) with a context.

This actually would not require an xperm, and in theory could be a dbus
only change! I think it would be nice however to support emitting the
dbus_contexts file from policy (similar to fc files and filecons in cil
and kernel policy language), although I understand this is a pretty big
change (although actually quite scoped) so very open to feedback on it.

Here is a snippet of pseudopolicy I came up with last night:

(in polkit

    (block dbus

      (dbuspeer peer "org.freedesktop.PolicyKit1")

      (type CheckAuthorization)
      (roletype .sys.role CheckAuthorization)

      (context CheckAuthorization_context (.sys.id .sys.role CheckAuthorization .sys.lowlow))

      (dbuscon system "/org/freedesktop/PolicyKit1/Authority"
       "org.freedesktop.PolicyKit1.Authority" "CheckAuthorization" peer
       CheckAuthorization_context)))

(type mysubj)
(roletype .sys.role mysubj)

(allow mysubj .polkit.dbus.CheckAuthorization (dbus (send)))

We then wire up dbus to support labelling members as the IPC endpoints
with a context, and have the dbuscon statements emit a dbus_contexts
file.

dbuscon isn't really a requirement, although I think it would be a nice
to have. Regardless, I'll wait a bit before submitting any patches to
the dbus upstream at FDO incase anyone from the community has design
concerns or feature requests they'd like implemented, considering this
is a pretty major change to dbus, community approval is desired in the
design.

>
> [1] https://www-old.cs.utah.edu/flux/fluke/html/dtos/HTML/dtos.html
>
>> [1] https://github.com/systemd/systemd/issues/8846
>> [2] https://source.android.com/docs/core/architecture/hidl/binder-ipc#names
>> [3] https://man.archlinux.org/man/apparmor.d.5.en#DBus_rules
>>
>> Thoughts/suggestions?
>> Rahul


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-11-07 15:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-06 19:57 DBus Permissions Rahul Sandhu
2025-11-07 13:28 ` Stephen Smalley
2025-11-07 13:56   ` Stephen Smalley
2025-11-07 15:28   ` Rahul Sandhu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.