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!
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.
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.
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?
(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?
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.
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.
(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.
(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.)
(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 :-).
Any chance this will get fixed?
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.
(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.
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
(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.
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.
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).
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?
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.)
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?
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
Will these transitions happen automatically on exec() with the new policy, or will we need to add a setexecon call or something?
automatically.
CLosed as this should be fixed in rawhide. If this problem persists please reopen the bugzilla.