Bug 329601 - Need domain transition for D-Bus system activation
Need domain transition for D-Bus system activation
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: selinux-policy-targeted (Show other bugs)
rawhide
All Linux
low Severity low
: ---
: ---
Assigned To: Daniel Walsh
Ben Levenson
:
Depends On:
Blocks: F8Target F9Blocker
  Show dependency treegraph
 
Reported: 2007-10-12 11:40 EDT by David Zeuthen
Modified: 2013-03-05 22:52 EST (History)
9 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-03-05 17:19:05 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description David Zeuthen 2007-10-12 11:40:24 EDT
A new feature in D-Bus is system bus activation, see

http://gitweb.freedesktop.org/?p=dbus/dbus.git;a=blob;hb=HEAD;f=doc/system-activation.txt

for details. 

We have this in Fedora now; the helper is located in
/lib/dbus-1/dbus-daemon-launch-helper, has mode 4750 and is owned by root:dbus.
This is to ensure only the system message bus (running as user 'dbus') can
execute this program; in addition the setuid bit is set so it will run as root. 

However, the SELinux security is wrong; programs that are started by the helper
has the wrong security context.

Consider this application that uses system bus activation

http://koji.fedoraproject.org/koji/buildinfo?buildID=20260

To test it, you need to remove your clock in the panel and add the new
"International Clock" applet. Then go in and add a few locations and press the
"Set" button while hovering over location; like this

http://people.freedesktop.org/~david/intlclock-applet.png

Pressing the "Set" button will put up a password dialog; that's unimportant for
this discussion because the system service used by the clock applet will already
have been activated because the clock applet itself called into the D-Bus
service org.gnome.ClockApplet.Mechanism:

$ ps auxZ|grep gnome-clock-applet-mechanism
system_u:system_r:system_dbusd_t root    23415  0.1  0.0   3800  1864 ?        S
   08:26   0:00 /usr/libexec/gnome-clock-applet-mechanism

 (note that the gnome-clock-applet-mechanism program will exit by itself
  within 30 seconds if it's not used)

As you can see this is running in the wrong security context. 

The desired effect is that this will run in the same context as if it was
started by an initscript. E.g. if that particular D-Bus service is confined
using SELinux I expect it to run under hald_t, cupsd_t or whatever the policy
prescribes. If it is not confined using SELinux I expect it to run as
unconfined_t. Especially the latter is going to happen now that developers start
using system bus activation.

Note that it's not enough to use the same context as the caller (e.g. the user
running the clock applet) who calls into the service; other users on the system
may call into the system service too; system services are genuinely shared
resources.

There is some more information here

 http://lists.freedesktop.org/archives/packagekit/2007-October/000563.html
 http://lists.freedesktop.org/archives/packagekit/2007-October/000567.html

about another system activated service which ran into the same problems.

It would be good to fix this for F8, as without this fix system activation will
not work on a system in SELinux enforcing mode. So I'm adding it to the blocker
list. Thanks!
Comment 1 Will Woods 2007-10-19 13:35:23 EDT
Two questions: 
1) How hard is it to implement domain transition for dbus, and
2) What will be broken until this bug is fixed?

I agree it's important to have, but I'm not convinced we need to block the
release  for it - at least not from the examples given. Moving to F8Target for now.
Comment 2 Daniel Walsh 2007-10-19 14:17:55 EDT
I believe this is a post F8,  I think we need to experiment in Rawhide.  The
best solution would be to have transitions to locked down domains.

Unconfined_t -> system_dbus_d -> clock_setting_t

They we could govern via dbus policy that unconfined_t can set the clock
settings and xguest_t can not.

Otherwise if we did end up with 

unconfined_t -> system_dbus_t -> unconfined_t
xguest_t -> system_dbus_t -> xguest_t

You would end up with a lot of avc's with xguest_t.

This is a clasic place where SELinux can be used to lock down an extension of
the OS that could allow users to break into the system.

If you can trick the code in any way to not set the clock settings but instead
bring down the firewall or read data owned by others, we have failed.
Comment 3 Nalin Dahyabhai 2007-11-06 12:01:11 EST
By "shared resources", do you mean that the process which the activation helper
starts is long-running, in that it services requests for multiple users until it
exits at a time of its own choosing?  Or is it one-shot, with a different copy
started for each request?  Or is it per-client, with a different copy started
for each client, potentially handling multiple requests from that client?
Comment 4 David Zeuthen 2007-11-06 15:19:49 EST
(In reply to comment #3)
> By "shared resources", do you mean that the process which the activation helper
> starts is long-running, in that it services requests for multiple users until it
> exits at a time of its own choosing?  

That's what I mean. Think of activation as merely an optimization to avoid
starting daemons at boot-time.

> Or is it one-shot, with a different copy
> started for each request?  Or is it per-client, with a different copy started
> for each client, potentially handling multiple requests from that client?

Comment 5 David Zeuthen 2007-11-15 12:19:06 EST
Dan, how about fixing this bug? 

With a number of things already using this feature in Rawhide already, this
makes SELinux look bad. When e.g. using PackageKit to update my system I get a
"AVC Denial" popup on my desktop roughly every five seconds. This is making me
want to uninstall setroubleshoot.

The best way to test that your feature works is to update gnome-panel, add the
intlclock applet and try changing your timezone.
Comment 6 Daniel Walsh 2007-11-15 13:33:03 EST
I have been concentrating on Fedora 8 this week and probably next.  Have not
even upgraded to Rawhide yet.


I see you talking about two different things here.

One is a daemon that is started by dbus instead of init. 

For example a user logging in might tell dbus to start the bluetooth daemon.  Or
maybe hal notices a bluetooth device calls to dbus to start bluetooth daemon. 
So dbus has to transtion to bluetooth. 

The second example is a user requesting something of dbus and you expecting dbus
to start the daemon as the user.  This is really not what we want.  I believe we
want a policy written for the app.  To control what the app does.  We will have
many cases where a confined user is logged in an might want to execute commands
via dbus.  Even if we wanted user_u -> dbus -> user_u to work correctly, we
can't write that in policy.  We would need to make dbus set the next context.  

On the user bus we can write user_t -> user_dbus_t -> user_t but in the system
case we can not differentiate between user_t -> system_dbus_t -> user_t and 
xguest_t -> system_dbus_t -> xguest_t.


Comment 7 David Zeuthen 2007-11-15 14:18:21 EST
(In reply to comment #6)
> I have been concentrating on Fedora 8 this week and probably next.  Have not
> even upgraded to Rawhide yet.
> 
> 
> I see you talking about two different things here.
> 
> One is a daemon that is started by dbus instead of init. 
> 
> For example a user logging in might tell dbus to start the bluetooth daemon.  Or
> maybe hal notices a bluetooth device calls to dbus to start bluetooth daemon. 
> So dbus has to transtion to bluetooth. 
> 
> The second example is a user requesting something of dbus and you expecting dbus
> to start the daemon as the user.  This is really not what we want.  I believe we
> want a policy written for the app.  To control what the app does.  We will have
> many cases where a confined user is logged in an might want to execute commands
> via dbus.  Even if we wanted user_u -> dbus -> user_u to work correctly, we
> can't write that in policy.  We would need to make dbus set the next context.  
> 
> On the user bus we can write user_t -> user_dbus_t -> user_t but in the system
> case we can not differentiate between user_t -> system_dbus_t -> user_t and 
> xguest_t -> system_dbus_t -> xguest_t.

No, I am not talking about having the bus daemon start a daemon as user 'foo'
just because user 'foo' calls into the bus. It is well-defined what user the
daemon is started as; it's normally root but it can also be an unprivileged
system user such as 'haldaemon' or 'avahi' or whatever.

The way it works is that D-Bus system bus activation simply just starts a
process running as root (or whatever the .service file says) once someone tries
to start a service. D-Bus system bus activation is simply just an optimization
so we don't need to start zillions of services at boot time. As such, it needs
the same transition rules as what we do with init.

Here's an example. Look at the new intlclock. To set the time zone it uses a
helper service on the system message bus called org.gnome.ClockApplet.Mechanism
that runs as root. It needs to run with privileges since setting the time and
changing timezones etc. require privileges.

$ cat /usr/share/dbus-1/system-services/org.gnome.ClockApplet.Mechanism.service 
[D-BUS Service]
Name=org.gnome.ClockApplet.Mechanism
Exec=/usr/libexec/gnome-clock-applet-mechanism
User=root

ls -lZ /usr/libexec/gnome-clock-applet-mechanism 
-rwxr-xr-x  root root system_u:object_r:bin_t       
/usr/libexec/gnome-clock-applet-mechanism

Without any SELinux policy for /usr/libexec/gnome-clock-applet-mechanism I would
except this would run unconfined. This isn't the case right now; it's running in
dbusd_t:

avc: denied { read } for comm=gnome-clock-app dev=proc egid=0 euid=0
exe=/usr/libexec/gnome-clock-applet-mechanism exit=9 fsgid=0 fsuid=0 gid=0
items=0 name=stat pid=16021 scontext=system_u:system_r:system_dbusd_t:s0 sgid=0
subj=system_u:system_r:system_dbusd_t:s0 suid=0 tclass=file
tcontext=system_u:system_r:unconfined_t:s0 tty=(none) uid=0 

Of course, I would welcome adding some policy for this particular program and
then I suppose it would look like the output of 'ls -lZ' would be different and
it would run in a confined security context.

Is it more clear now what we're trying to achieve? E.g. you should treat system
bus activation as the way you treat init. It's simply just an optimization to
avoid starting lots of helper D-Bus system daemons at boot up.
Comment 8 David Zeuthen 2007-11-15 14:22:31 EST
(In reply to comment #6)
> The second example is a user requesting something of dbus and you expecting dbus
> to start the daemon as the user.  This is really not what we want.  

(Btw, I'm not sure why this would be useful either... Normally people use the
system bus only when they need someone more privileged to carry out work on
their behalf.)
Comment 9 Matěj Cepl 2008-02-05 05:47:15 EST
(In reply to comment #2)
> I believe this is a post F8, ...

sure, and unless we will do something about it, it will be post F9 soon :-).
Comment 10 David Zeuthen 2008-02-24 15:20:51 EST
Any chance this will get fixed?
Comment 11 Daniel Walsh 2008-02-26 09:59:08 EST
This bug is too broad.  Rawhide policy currently allows the management of the
clock via policykit/hal.

I need other examples of breakage.

It also allows some system services to be started via dbus.

So opening bugs of what is broken, rather then dbus must be able to start stuff
for the user.
Comment 12 David Zeuthen 2008-02-26 10:43:01 EST
(In reply to comment #11)
> This bug is too broad.  Rawhide policy currently allows the management of the
> clock via policykit/hal.

I don't see why this bug is too broad. And there's also PackageKit and other
examples of system bus activation. It's general infrastructure.

> 
> I need other examples of breakage.
> 
> It also allows some system services to be started via dbus.
> 
> So opening bugs of what is broken, rather then dbus must be able to start stuff
> for the user.

No, this is not going to work. Please understand that system bus activation is
general infrastructure for starting services on *demand* exactly like
/etc/init.d is general infrastructure for starting services on *bootup*. Can you
see that there is no difference?

Go back and read comment 7 for more details.
Comment 13 Daniel Walsh 2008-02-26 10:55:08 EST
Ok, system_dbusd_t should be able to execute all initrc scripts in the proper
context.

But this does not fix any userapp asking policykit to make changes via hal.

Fixed in selinux-policy-3.3.1-2.fc9
Comment 14 David Zeuthen 2008-02-26 11:03:56 EST
(In reply to comment #13)
> Ok, system_dbusd_t should be able to execute all initrc scripts in the proper
> context.

What are you talking about? I think you complete misunderstood my analogy.

Here's the deal. If I'm an 3rd party RPM I can drop an initscript and expect
that to run unconfined (assuming there's no SELinux policy for me) and I can
expect things to work.

What we're asking for here is exactly the same. If I'm a 3rd party RPM I can
drop a .service file in /usr/share/dbus-1/system-services and expect that
program to be started and run unconfined (assuming there's no SELinux policy for
me) and I can expect things to work.

Do you see what I mean?

It needs to work this way.

Thanks.
Comment 15 Daniel Walsh 2008-02-26 11:14:47 EST
Yes and that is going to happen with the latest change.    

Currently the system is configured to start daemons via init scripts.  
init_t -> initrc_exec_t -> initrc_t -> domain_exec_t -> domain_t
For confined domains
init_t -> initrc_exec_t -> initrc_t -> bin_t -> initrc_t
For unconfined domains (initrc_t is unconfined for targeted policy)

New policy allows

system_dbusd_t -> initrc_exec_t -> initrc_t -> domain_exec_t -> domain_t 
for confined domains

Or 
system_dbusd_t -> initrc_exec_t -> initrc_t -> bin_t -> initrc_t
For unconfined domains (initrc_t is unconfined for targeted policy)

So a third party can drop a package in place and it will work.

Policy is building you can try it out when it completes.
Comment 16 David Zeuthen 2008-02-26 11:18:07 EST
OK, sounds good. Hopefully that get rids of the last AVC's I'm seeing (I have a
few system bus activated services in a project not yet in Fedora that I'm
hacking on).
Comment 17 Ray Strode [halfline] 2008-02-26 11:39:47 EST
Hi Dan,

I've got two questions,

1) What does the actual domain transitions (the -> s in your chart i mean).  Is
this automatic on execve() or do we have to add code to move between domains?
2) Shouldn't we only allow the setuid dbus-launch-helper the ability to start
daemons, and not dbus-daemon itself?

Comment 18 Daniel Walsh 2008-02-26 12:23:27 EST
Nalin and I have been discussing this on Chat.

exec_t/bin_t mean file types, all others are process types (domains in SELinux
lingo).

The current policy does not allow for the correct transition.

My current thinking on this is to label 

dbus-daemon-launch-helper system system_dbusd_exec_t

Then allow system_dbusd_t to exec system_dbusd_exec_t

Now current policy allows system_dbusd_t to execute consolekit_exec_t and
transition to consolekit_t (policykit also has similar policy)

Now optionally, we want to allow
system_dbusd_t to execute bin_t apps and transition to initrc_t.  (initrc_t is
an unconfined domains, but it will transition properly to a confined domain if
the app executes one.)

Comment 19 Bill Nottingham 2008-02-26 12:30:09 EST
One issue I see - having initrc_exec_t in the middle won't work if the thing
dbus is exec()ing isn't an init script, correct?
Comment 20 Daniel Walsh 2008-02-26 13:16:34 EST
Yes.  My first solution was wrong.  initrc_exec_t does not come into play.

My new solution is 
                  (dbus-daemon-launch-helper)

system_dbusd_t -> system_dbusd_exec_t -> system_dbusd_t -> domain_exec_t -> domain_t
And optionally controlled by boolean:

system_dbusd_t -> system_dbusd_exec_t -> system_dbusd_t -> bin_t -> initrc_t
Comment 21 Ray Strode [halfline] 2008-02-26 13:26:18 EST
Will these transitions happen automatically on exec() with the new policy, or
will we need to add a setexecon call or something?

Comment 22 Daniel Walsh 2008-02-26 13:45:08 EST
automatically.

Comment 23 Daniel Walsh 2008-03-05 17:19:05 EST
CLosed as this should be fixed in rawhide.  If this problem persists please
reopen the bugzilla.

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