Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 526532 - net-analyzer/munin installs a cron with incorrect user context
Summary: net-analyzer/munin installs a cron with incorrect user context
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: SELinux (show other bugs)
Hardware: All Linux
: Normal major (vote)
Assignee: Sven Vermeulen (RETIRED)
URL:
Whiteboard: sec-policy r1
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-22 22:30 UTC by Eric Gisse
Modified: 2014-12-21 14:11 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Gisse 2014-10-22 22:30:10 UTC
Note: This system is running permissive rather than enforcing selinux.

When munin is installed with +cron, /var/spool/cron/crontabs/munin is created.

This has a selinux context of: 

root:object_r:user_cron_spool_t

When cron (specifically, vixie-cron) runs, you get the following whine in the logs:

Oct 22 22:08:39 testbed cron[29465]: (CRON) STARTUP (V5.0)
Oct 22 22:08:39 testbed cron[29465]: (munin) ENTRYPOINT FAILED (crontabs/munin)

After some digging, it appears that the munin user created does not have a specific context:

# semanage login -l

Login Name                SELinux User             

__default__               user_u                   
root                      root                     
system_u                  system_u   

Once the user context is changed to the catchall of user_u ...

# ls -Z /var/spool/cron/crontabs/munin
user_u:object_r:user_cron_spool_t /var/spool/cron/crontabs/munin

...everything is happy:

Oct 22 22:13:24 testbed cron[29521]: (CRON) STARTUP (V5.0)
Oct 22 22:15:01 testbed cron[29531]: (munin) CMD (/usr/bin/munin-cron)

Now, I am not sure where the bug is to be honest.

If I generate the munin cron entry through puppet (which I tried, actually, to see what would happen) the same issue appears.

So is this an issue with munin for not generating a munin-specific context and cron for not using it? 

Or is it a bug with the selinux defaults themselves? I am kinda leaning towards this.

# matchpathcon /var/spool/cron/crontabs/munin
/var/spool/cron/crontabs/munin  <<none>>

So there's no specific context for munin, which means it is inheriting the root user's context rather htan using __default__ (user_u).

Could this be fixed by putting the user context for that within the munin policy, or would this have to be fixed through the cron policy? ::notsure::

Filing this as major due to munin being nonfunctional with the defaults.

Reproducible: Always
Comment 1 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-01 18:30:31 UTC
Wouldn't it be more logical that munin runs as the system_u user (so all we need to do is make a mapping from munin -> system_u)? The user_u SELinux user is meant for end users while munin is a system process
Comment 2 Eric Gisse 2014-11-01 19:58:01 UTC
Either way would work, I would argue. It just needa *some* sort of mapping.

I'm not sure what the right answer would be.

On one hand, user_u strikes me as the selinux user meant for "real" users and I'm not sure mixing in services with that namespace is the best idea.

On the other, munin *does* drop privileges frequently (and explicitly) to various users (munin, nobody, root) for its' own purposes.

Now, while I am serious about using SELinux on my Gentoo testbed platform, it is more in the sense of securing some public services I run and thus serves as a useful vehicle for teaching myself something interesting.

So going back to the selinux user issue, I really don't have any idea what the right answer is. Not because I haven't looked, but because there doesn't seem to be a best practices guide for this type of thing.

Thus I ask, why does it have to be either? Why not make a distinct selinux user, say munin_u? 

It isn't as if being system_u or user_u grants specific privileges unto themselves. So outside of some argument about polluting the selinux user namespace, I feel that's a reasonable option. 

I grant I'm feeling this out as I go and am not sure if there's an overall Gentoo position on how this "should be".
Comment 3 Eric Gisse 2014-11-02 02:51:18 UTC
And this potentially touches on some other things, now that I'm *finally* going through the avc.log and working on things.

So every 5 minutes, cron runs /usr/bin/munin-cron 

This spits out a bunch of stuff via avc:

# grep munin-graph /var/log/avc.log | grep '20:45'
Nov  1 20:45:21 testbed kernel: [196706.907166] audit: type=1400 audit(1414892721.738:49513): avc:  denied  { getattr } for  pid=13462 comm="munin-graph" path="/var/log/munin/munin-graph.log" dev="dm-2" ino=262786 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:var_log_t tclass=file permissive=1
Nov  1 20:45:21 testbed kernel: [196706.907270] audit: type=1400 audit(1414892721.738:49514): avc:  denied  { append } for  pid=13462 comm="munin-graph" name="munin-graph.log" dev="dm-2" ino=262786 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:var_log_t tclass=file permissive=1
Nov  1 20:45:21 testbed kernel: [196706.907289] audit: type=1400 audit(1414892721.738:49515): avc:  denied  { open } for  pid=13462 comm="munin-graph" path="/var/log/munin/munin-graph.log" dev="dm-2" ino=262786 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:var_log_t tclass=file permissive=1
Nov  1 20:45:21 testbed kernel: [196706.907314] audit: type=1400 audit(1414892721.738:49516): avc:  denied  { ioctl } for  pid=13462 comm="munin-graph" path="/var/log/munin/munin-graph.log" dev="dm-2" ino=262786 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:var_log_t tclass=file permissive=1
Nov  1 20:45:21 testbed kernel: [196706.912116] audit: type=1400 audit(1414892721.743:49517): avc:  denied  { write } for  pid=13462 comm="munin-graph" name="testbed" dev="dm-2" ino=263342 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:httpd_sys_content_t tclass=dir permissive=1
Nov  1 20:45:21 testbed kernel: [196706.912134] audit: type=1400 audit(1414892721.743:49518): avc:  denied  { remove_name } for  pid=13462 comm="munin-graph" name="cpu-day.png" dev="dm-2" ino=282761 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:httpd_sys_content_t tclass=dir permissive=1
Nov  1 20:45:21 testbed kernel: [196706.912149] audit: type=1400 audit(1414892721.743:49519): avc:  denied  { unlink } for  pid=13462 comm="munin-graph" name="cpu-day.png" dev="dm-2" ino=282761 scontext=user_u:user_r:cronjob_t tcontext=user_u:object_r:httpd_sys_content_t tclass=file permissive=1
Nov  1 20:45:21 testbed kernel: [196706.930602] audit: type=1400 audit(1414892721.761:49520): avc:  denied  { read } for  pid=13462 comm="munin-graph" name="conf.d" dev="dm-2" ino=412174 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:fonts_t tclass=dir permissive=1
Nov  1 20:45:21 testbed kernel: [196706.930629] audit: type=1400 audit(1414892721.761:49521): avc:  denied  { getattr } for  pid=13462 comm="munin-graph" path="/etc/fonts/conf.d" dev="dm-2" ino=412174 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:fonts_t tclass=dir permissive=1
Nov  1 20:45:21 testbed kernel: [196706.930652] audit: type=1400 audit(1414892721.761:49522): avc:  denied  { open } for  pid=13462 comm="munin-graph" path="/etc/fonts/conf.d" dev="dm-2" ino=412174 scontext=user_u:user_r:cronjob_t tcontext=root:object_r:fonts_t tclass=dir permissive=1

Nothing there is unexpected, to be honest. munin-graph likes to put its' output into /var/www/*, put log output into /var/log, etc. 

I am running as user_u as a hack-fix which helped, but obviously not completely.

Now, did my changes spur this? I don't believe so - the cron job would be running under an unprivileged and nonspecific context either way.

This is another point in favor of creating a munin_u selinux user that can be granted the permissions necessary, because otherwise they would have to be granted to user_u (bad) or system_u (not as bad, but highly suboptimal).

The munin-update command has largely the same avc log entries as well, plus this goofball:

Nov  1 21:40:25 testbed kernel: [200012.826640] audit: type=1400 audit(1414896025.040:50204): avc:  denied  { remove_name } for  pid=17893 comm="/usr/libexec/mu" name="munin-testbed-testbed.lock" dev="tmpfs" ino=74031915 scontext=user_u:user_r:cronjob_t tcontext=system_u:object_r:munin_var_run_t tclass=dir permissive=1

I think a lockfile is being made in /usr/libexec/munin and that's the result, though I have no idea why its' being truncated.

There is also similar issues with the bind9_rndc but I haven't fully sorted out whether that's my fault due to how hard puppet's bind module screws with the defaults...

This doesn't, to me, appear to have a super clean fix and has tendrils EVERYWHERE.
Comment 4 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-02 14:16:48 UTC
The choice of SELinux users affects the roles in which a domain can run. Also, if USE="ubac" is set, then user_u running processes do not have access to resources owned by other SELinux users (except system_u). One of the reasons to run system daemons in system_u is exactly that - to ensure they can access other SELinux users' resources when UBAC is enabled.

Personally, I'd go with system_u.

Regarding the running resources in cronjob_t - it is best practice that the cron job (for munin here) immediately transitions to a munin-specific domain. There is a "cron_system_entry(munin_t, munin_exec_t)" which allows system_cronjob_t to transition to munin_t.

As you're running the resources in cronjob_t (which is for end users, not system daemons) the transition doesn't fly.

You should focus on having the munin cronjobs run through the system cron, not end user crons. At least, that is how the current policy is tailored for.
Comment 5 Eric Gisse 2014-11-02 17:10:53 UTC
The cronjob context transition discussion mirrors the selinux cron wiki discussion. I understand that it should be doing that transition. The problem is that it isn't. 

Yes, the resources are running in cronjob_t but that's *not* a choice I made but rather is the result of what emerge --config net-analyzer/munin spits out because the file context it gets labeled with seems to be inheriting from how /var/spool/cron/crontabs/ itself is labeled.

I don't blame the config script for this, as managing this via puppet (I like puppet) spits out the same context result.

But that is, once again, an artifact of the munin crontab entry not having a specific default context:

# matchpathcon /var/spool/cron/crontabs/munin
/var/spool/cron/crontabs/munin  <<none>>

Taking your suggestion into consideration now that I understand the role of system_* a bit better, I chcon'd the munin crontab entry from user_u to system_u and that *appears* to resolve the issue.

And in furthering my own understanding, I think I see why:

Under the system_u user, things get the system_r role. The system_r role in turn gets the system_cronjob_t context, which THEN allows the policy-defined cron to munin_t transition.

The user_u user context doesn't have that escalation path.

So assuming this solution is acceptable, would adding the cron file context to munin.fc like this be satisfactory?

/var/spool/cron/crontabs/munin  -- gen_context(system_u:object_r:cron_spool_t,s0)

Is it OK to override a cron entry like this? I'm not sure, but it works.
Comment 6 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-08 16:05:32 UTC
The problem with that definition is that /var/spool/cron/crontabs/ is the location for regular end user crontabs. So if someone would use a nickname of "munin", then his or her crontab would be /var/spool/cron/crontabs/munin.

I can ask upstream policy about it, but I think they would suggest to have the crontab file moved to the /etc/cron.d location instead.

We can easily document it on the cron SELinux page of course (and in the manual page).
Comment 7 Eric Gisse 2014-11-08 19:15:41 UTC
Yeah, /etc/cron.d/munin or whatever would work fine.

Would still need a file context entry though, but that's easy.

What happens, though, if the munin package moves to putting stuff in cron.d and a system installs the new package and now you have both running?

Put something in the ebuild to migrate? 

WHY SO DIFFICULT?
Comment 8 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-11 09:09:11 UTC
The difficulty is that there are multiple ways to do things, and a policy in a MAC (Mandatory Access Control) system will support one (or a few) ways. Purely technical speaking, using user cron jobs for munin works (otherwise it wouldn't be installed like that).

The SELinux policy that we use is based on the reference policy (note that SELinux itself is the means to enforce a policy, and that we install *a* possible policy) which has a particular setup for cron in mind, which does not allow end user cron jobs the same set of permissions (and even access paths) than system jobs - hence its differentiation between system_cronjob_t and cronjob_t. And depending on a particular setup/boolean definition, end user cron jobs even run in the user domain (like user_t) instead of the cronjob domain (cronjob_t).

Regarding this particular bug, I will
- document the cron stuff in a cron_selinux manual page with a section specific to the munin case
- document the same on the wiki
- investigate if we can (and should) have portage install files as system_u by default (i'll do this through a different bug)
Comment 9 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-11 13:27:58 UTC
Okay; with selinux-base revision 8 we will include munin_selinux and cron_selinux manual pages. In the cron_selinux manual, the impact and handling of crontab files is documented in more detail. A BUGS section at the end informs the user about the Munin case. Same with munin_selinux.

On the wiki, I added "Policy module specific information" [1] as part of the Reference material [2]. On that page, the wikified versions of the manual pages of munin_selinux [3] and cron_selinux [4] are accessible.

[1] https://wiki.gentoo.org/wiki/SELinux/Module_list
[2] https://wiki.gentoo.org/wiki/SELinux
[3] https://wiki.gentoo.org/wiki/SELinux/munin
[4] https://wiki.gentoo.org/wiki/SELinux/cron
Comment 10 Sven Vermeulen (RETIRED) gentoo-dev 2014-11-11 13:38:37 UTC
I also noticed that files installed by Portage do inherit the system_u owner (if portage is running in the right domain of course) as long as the file(s) installed have a specified label.

As such, I've implemented your suggestion in the policy (even though I initially thought it was a bad idea, but at least the workaround allows for end users to continue without having to take any action themselves).

Will be part of r8 as mentioned earlier.
Comment 11 Eric Gisse 2014-11-12 01:38:12 UTC
Yeah, I do see that Gentoo runs "a" reference policy. I know there can be others but I don't think anyone does. I think even RHEL uses the Tresys reference policy, but I'm not 100% sure.

So my approach with these things is very much "a path of least resistance". On one hand I want to keep in line with what I consider administrative best practices, but on the other I don't want to have to engage a low level ground war with the selinux policy just to have it my way. 

So compromises have to be made :)

I really don't know what the "right" answer is for cron issues like this, because the transition policies and permissions you have to set up give me a headache. 

It just seems easier to hardcode the proper context into the respective cron file itself, make sure cron can do the transition, and call it a day.

Especially since portage *does* take control of that user and its' associated cron regardless of selinux.
Comment 12 Eric Gisse 2014-11-18 18:52:30 UTC
In chatting with perfinion on irc, it was suggested that I move back into the 2.3 userspace. This has caused some issues with work I've done, because apparently 2.4 is way, way, WAY more permissive than 2.3.

Like this, for example, when I build policy modules using 2.3 userspace:

 * Inserting the following modules, with base, into the strict module store: application authlogin bootloader clock consoletype cron dmesg fstools getty hostname hotplug init iptables libraries locallogin logging lvm miscfiles modutils mount mta netutils nscd portage raid rsync selinuxutil setrans ssh staff storage su sysadm sysnetwork tmpfiles udev userdomain usermanage unprivuser xdg
/etc/selinux/strict/contexts/files/file_contexts: Multiple different specifications for /var/spool/cron/crontabs/munin  (system_u:object_r:cron_spool_t and system_u:object_r:system_cron_spool_t).
/etc/selinux/strict/contexts/files/file_contexts: Invalid argument
libsemanage.semanage_install_active: setfiles returned error code 1.
semodule:  Failed!

Apparently the generic wildcard labeling of cron with the more specific labeling is a policy conflict in 2.3 userspace.
Comment 13 Sven Vermeulen (RETIRED) gentoo-dev 2014-12-21 14:11:54 UTC
r1 is now stable