* 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