Some people on #selinux are … dolphins

A very useful resource for anyone working on or with SELinux policies is the #selinux chat channel on irc.freenode.net. People like Dominick Grift and Dan Walsh you would first think are IRC bots (being online all the time, answering questions), but I recently read that they must be … dolphins.

Yes, dolphins. Dolphins are known to not really sleep fully – only one part of their brain goes to a low-wave sleep so they’re sufficiently conscious to keep track of what is happening around them.

No seriously, thanks guys!

Posted in SELinux | Leave a comment

On the new SELinux profiles

Ever since Anthony put in the new SELinux profiles – which was long due – they have seen quite a few tests and the necessary, evolutionary updates. No changes that broke things, no oddities that would give a WTF to whomever is using it. The latest updates were to remove some obsolete masks so that our visibility in the Gentoo QA Reports is down again.

However, we are well aware that these profiles are still in the dev(elopment) phase but would like to stabilize these soon. For this to happen, we need SELinux users to give the new profiles a go. Become sysadm_r & root and switch your profile to whichever SELinux profile suits you the most (with the new profiles, we support SELinux on multilib and no-multilib and across various settings).

All my local servers run with “hardened/linux/amd64/no-multilib/selinux” whereas my main workstation uses “hardened/linux/amd64/selinux” (since I still have some need for the multilib setup). We did some tests on non-hardened profiles too as well as on the x86 architecture with no problems whatsoever. So although we can’t guarantee anything, I’m pretty convinced that the profiles will work for you too!

So by all means, see if you can switch from the v2refpolicy/ profiles and give us your feedback. You’re always welcome for a chat on #gentoo-hardened (irc.freenode.net) or on our mailinglists.

Posted in Hardened | Leave a comment

Gentoo Hardened SELinux state

Since last post, we’ve been working on the further stabilization and bug fixing of the SELinux policies within Gentoo Hardened. You might have noticed that we started working on the QA of the packages, like I promised in the last post. The binaries within selinux-base-policy are now published somewhere on blueness’ developer page since he’s proxy’ing all my commits until recruiters get the chance to pick up my recruitment bug. Other patches that are coming up will be published likewise as well if they get too big to be within the main Portage tree.

Next to the binaries, I’m currently checking if the SELinux policy packages can become EAPI-4 compliant (they’re currently still using EAPI-0). Same for the SELinux-specific packages, like policycoreutils, libsemanage, libselinux etc.

During the last few days, I’ve tried to take a few stabs at supporting Python 2 and Python 3 simultaneously. It seems to work for policycoreutils and libsemanage (necessary fixes are in the gentoo-hardened overlay) but any attempt to fix libselinux seems to give me hard walls. So for now, we’re still stuck with Python 2 support when using Portage (note that you can still use Python 3 for all other things, but Portage requires Python 2 as it calls libselinux). This is currently still accomplished through a proper use.mask and use.force setting against Portage.

Of course, the policies themselves are not silent either. I’ve updated the selinux-base-policy package so that Portage can now support NFS-mounted Portage trees and made quite a few openrc-related fixes as well (against the policy, not against openrc ;-)

I promised to take a stab at MCS in the near future, and that’s still the plan. Hopefully in the coming few weeks ;-)

Posted in Hardened, SELinux, Uncategorized | Leave a comment

What’s next after stabilization?

The last few weeks have shown quite a few interesting improvements on Gentoo Hardened’s SELinux state. We now have improved (simplified) Gentoo profile support, supporting SELinux on no-multilib (an often requested feature, now finally in), we stabilized the 2.20101213 policies that are in the tree and are cleaning up the old ones. The documentation is continuously updated (handbook and FAQ) and we are getting a nice stream of users helping out and reporting stuff on SELinux.

So, besides the further stabilization and bug fixing, what else is on the horizon?

Well, our first concern now will be to make the ebuilds more… correct. Some of them still violate a few QA rules and this needs to be fixed. If possible, we’ll also start converting our ebuilds to a more recent EAPI.

Then, we will take a first stab at MCS within Gentoo Hardened. Our primary concern here is support for the virtualization technologies which, if SELinux-aware, are often using MCS to shield off running guests from each other.

So interesting times are ahead. And of course, while we’re at it, we’ll continue improving policies and submitting our own patches upstream.

Posted in Hardened | Leave a comment

Policy 25, 26

Recently I’ve seen quite a few messages on IRC pop up about policy.25 or even policy.26 so I harassed the guys in the chat channel to talk about it. Apparently, these new binary policy formats add support for filename transitions and non-process role transitions.

Currently, when you initiate a type transition, you would use something like so:

type_transition mysqld_t mysql_db_t:sock_file mysqld_var_run_t;

This statement sais that, if a process running in the mysqld_t domain creates a socket in a directory labelled with mysql_db_t, then this socket gets the mysqld_var_run_t label. In other words, the type transitions from mysql_db_t (parent label) to mysqld_var_run_t.

What will be supported from version 25 onwards is that you can add another argument, the file name (well, actually it is called “last name component” and should be seen as what basename /path/to/something returns). That allows processes running in the same domain and writing files in directories labelled with the same type to still have these files labelled specifically. A non-existing example:

type_transition puppet_t etc_t:file locale_t timezone;
type_transition puppet_t etc_t:file net_conf_t resolv.conf;

In the above example, if the puppet_t domain creates files in /etc (which is labelled etc_t) then based on the file it is creating, this file gets a different label (/etc/timezone gets labelled locale_t whereas /etc/resolv.conf gets labelled net_conf_).

The second change (valid since policy version 26) is that role transitions now also support non-process class transitions. A lengthy post that Harry Ciao made helps to describe it. The role_transition support in SELinux was previously used in the following way:

role_transition roleA_r some_exec_t roleB_r;

What this statement indicates is that a domain running within roleA_r and that is executing some_exec_t will change its runtime role to roleB_r. If by calling some_exec_t a domain transition occurs as well (which is most common when a role transition is supported as well) then this domain will run with the roleB_r runtime role.

The added functionality is now that this isn’t limited to processes anymore. You can now define non-process classes as well. If the source domain creates something new of a particular class and a role transition is declared for that, then the resulting new object will have the specified role assigned to it (rather than the default object_r). So for instance:

role_transition sysadm_r cron_spool_t:file sysadm_r;

If a domain running within the sysadm_r role creates a file in a directory labelled cron_spool_t, then the resulting file will have the role sysadm_r rather than object_r. This opens up more support for role-based access controls (similar to the UBAC functionality that I described earlier, but in some cases more flexible). I’m pretty sure that the crontab management for vixie-cron will be one of the first ones that can benefit greatly from this ;-)

Posted in SELinux | 2 Comments

SELinux file contexts

If you have been working with SELinux for a while, you know that file contexts are an important part of the policy and its enforcement. File contexts are used to inform the SELinux tools which type a file, directory, socket, … should have. These types are then used to manage the policy itself, which is based on inter-type permissions.

When dealing with file contexts, you either use

  • chcon (mostly) if you are trying out stuff as a chcon-set security context doesn’t stick after a file system relabel operation (customizable types notwithstanding, and even then)
  • restorecon if you want to reset the file context of a file or set of files
  • semanage through the semanage fcontext -a -t your_type “regular_expression” method, which enhances the SELinux known file contexts with the appropriate information so that relabel operations are survived
  • policy improvements by editing and enhancing the *.fc files that take part in the policy definition

When you look at the policy, or the output of semanage fcontext -l, you’ll notice that the policy uses regular expressions very often. Of course, without regular expression support, the file context rules themselves would be impossible to manage. However, it immediately brings up the question about what SELinux does when two or more lines are appropriate for a particular file. Let’s look at a few lines for configuration related locations…

/etc/.*                     all files          system_u:object_r:etc_t
/etc/HOSTNAME               regular file       system_u:object_r:etc_runtime_t
/etc/X11/[wx]dm/Xreset.*    regular file       system_u:object_r:xsession_exec_t
/etc/X11/wdm(/.*)?          all files          system_u:object_r:xdm_rw_etc_t

In the above examples, you’ll notice that there is quite some overlap. To start, the first line already matches all other lines as well. So how does SELinux handle this?

Well, SELinux uses the following logic to find the most specific match, and uses the most specific match then (extract taken from a pending update to the Gentoo Hardened SELinux FAQ):

  1. If line A has a regular expression, and line B doesn’t, then line B is more specific.
  2. If the number of characters before the first regular expression in line A is less than the number of characters before the first regular expression in line B, then line B is more specific
  3. If the number of characters in line A is less than in line B, then line B is more specific
  4. If line A does not map to a specific SELinux type, and line B does, then line B is more specific

So in case of /etc/HOSTNAME, the second line is most specific because it does not contain a regular expression.

In case of /etc/X11/wdm/Xreset.sh, SELinux will use the xdm_rw_etc_t type and not the xsession_exec_t one. This is because the first regular expression in the xsession_exec_t line ([wx]) comes sooner than the first regular expression in the xdm_rw_etc_t line ((/.*)?). You can validate this – even if you do not have such file – with matchpathcon:

~# matchpathcon /etc/X11/wdm/Xreset.sh
/etc/X11/wdm/Xreset.sh   system_u:object_r:xdm_rw_etc_t

If you want to know which line in the semanage fcontext -l output is used, you can use findcon to show which lines match. That together with the output of matchpathcon can help you deduce which line is causing the label to be set:

~# matchpathcon /etc/X11/wdm/Xreset.sh
/etc/X11/wdm/Xreset.sh   system_u:object_r:xdm_rw_etc_t
~# findcon /etc/selinux/strict/contexts/files/file_contexts -p /etc/X11/wdm/Xreset.sh
/.*             system_u:object_r:default_t
/etc/.*         system_u:object_r:etc_t
/etc/X11/[wx]dm/Xreset.*        --      system_u:object_r:xsession_exec_t
/etc/X11/wdm(/.*)?              system_u:object_r:xdm_rw_etc_t

In many cases, the last output line of findcon is the line you are looking for, but I have not find a source that confirms this behavior so do not trust this.

Posted in Hardened, SELinux | Leave a comment

SELinux Gentoo profile updates

The SELinux support within Gentoo Hardened is continuing to go forward. Anthony G. Basile has been working on the new SELinux Gentoo profiles which were in dire need of updates. With the rework, we’ll also support the AMD64 no-multilib environment properly. With the new profiles we’ll also make USE=”open_perms” enabled by default. This will enable the “open” permission within the SELinux policies. And of course we’ll remove that FEATURES=”loadpolicy”.

Not in git yet, but close, are further updates on the policy ebuilds. Revision 14 of our selinux-base-policy package will fail when the base policy couldn’t be loaded properly. This will ensure that a successful installation means that the policies are loaded successfully as well. If we wouldn’t do this, then users might assume that the policies are constantly being updated while in reality their system has always been working with older policies. I am also going to, based on the QA reports, update the sec-policy/* packages so they are not mentioned in those reports anymore.

In other related news, the Gentoo Hardened SELinux FAQ will get updates on UBAC, cron issues and a few errors (cosmetic or not) that you might have when working with Gentoo Hardened SELinux. I’m also constantly updating the Gentoo Hardened SELinux Handbook (PDF) with the latest information and developments.

Posted in Hardened | Leave a comment

SELinux User-Based Access Control

Within the reference policy, support is given to a feature called UBAC constraints. Here, UBAC stands for User Based Access Control. The idea behind the constraint is that any activity between two types (say foo_t and bar_t) can be prohibited if the user contexts of the resources that are using those types are different. So even though foo_t can read files with label bar_t, a process running as user1:user_r:foo_t will not be able to read a file labeled user2:user_r:bar_t. The policy defines the constraint like so (taken from policy/constraints and rewritten in a more readable code):

Action is okay if
  user1 == user2, or
  user1 == system_u, or
  user2 == system_u, or
  type1 is not a UBAC constrained type, or
  type2 is not a UBAC constrained type

So the constraint only denies an activity if the users involved are not system_u (that would render your system useless), not the same, and both types are ubac constrained types. The latter is, within the policy, set using type attributes:

~$ seinfo -aubac_constrained_type -x
ubac_constrained_type
   screen_var_run_t
   admin_crontab_t
   links_input_xevent_t
   ...

Some domains are also UBAC exempt (currently I know of the sysadm_t domain – cfr the ubacproc and ubacfile attributes), meaning that activities started from the sysadm_t domain will not trigger the constraint.

UBAC gives some additional control on information flow between resources. But it isn’t perfect. One major downside is that the error you get when the constraint is hit is a simple AVC denial where most users would just check the inter-type privileges, without paying attention to the difference in SELinux user identities. Another is that it might be difficult for users or administrators that use different SELinux user identities to still work properly with UBAC constrained domains. Work is on the way in the SELinux development to improve the role-based access control (RBAC) by allowing files and directories to have a role as well (rather than the object_r placeholder used currently) and then work on those roles. You can then grant the users that need access to a particular resource the necessary role rather than requiring those users to use the same SELinux user id. This would take at least one major downside of UBAC away and I’m hoping that the logging will improve on this as well.

Of course, I do not ramble about UBAC here because it is fun (well yes, yes it is fun) but because in Gentoo, we’ve hit one UBAC-related issue. When a user starts vixie-cron, the root crontab would fail to be loaded. What gives? The root crontab has the SELinux identity of staff_u (as it is created by a regular staff user that su(do)’ed) whereas the cronjob_t process would have the SELinux identity of root. Bang. Dead. No error beyond what vixie-cron gives.

Of course this can be easily worked around. chcon -u root /var/spool/cron/crontabs/root works, or you can recreate the crontab as a console-logged-on root user. We could also change the default context used by cronjob_t to use staff_u:sysadm_r:cronjob_t for root. But we can also take a look at how other distributions do this. What gives: most distributions disable UBAC within the policy. Their reasons might vary, but manageability of the policy comes to mind, as well as reducing the number of (difficult to debug) problems. Most are keen to include the RBAC at some point in the future though. Some discussion on #gentoo-hardened and #selinux later, and I decided to use a USE flag called “ubac” to optionally enable UBAC within the policy. How very Gentoo, isn’t it? At least users have the choice of using UBAC or not (I know I’m going to enable it) and when RBAC is available, we’ll definitely make sure that support for RBAC is available too.

Currently in the hardened overlay, sec-policy/selinux-base-policy-2.20101213-r13. Take your pick on it, give it a try and report any bugs you have on Bugzilla. And if you enable USE=”ubac”, you get user based access control for free.

PS I’m also going to reapply for Gentoo developer-ship and, amongst other things, help out the hardened team with SELinux policies and documentation.

Posted in Hardened, SELinux | 15 Comments

SELinux and noatsecure, or why portage complains about LD_PRELOAD and libsandbox.so

If you’re fiddling with SELinux policies, you will eventually notice that the reference policy by default hides certain privilege requests (which are denied). One of them is noatsecure. But what is noatsecure? To describe noatsecure, I first need to describe what atsecure is. And to describe what that is, we first need to give a small talk about ELF auxiliary vectors.

As you probably know, when an application instantiates another application, it calls the execve function right after fork’ing to load the new application in memory. The actual task to load the new application in memory is done by the C library, more specifically the binary loader. For Linux, this is the ELF loader. Now, ELF auxiliary vectors are parameters or flags that are set (or at least managed) by the ELF loader to allow the application and program interpreter to get some OS-specific information. Examples of such vectors are AT_UID and AT_EUID (real uid and effective uid) and AT_PAGESZ (system page size).

One of the vectors that glibc supports is AT_SECURE. This particular parameter (which is either “0″ (default) or “1″) tells the ELF dynamic linker to unset various environment variables that are considered potentially harmful for your system. One of these is LD_PRELOAD (I mention this one specifically because it was the source of my small investigation). Normally, this environment sanitation is done when a setuid/setgid application is called (to prevent the obvious vulnerabilities). However, SELinux enhances the use of this sanitation…

Whenever an application is called which triggers a domain transition in SELinux (say sysadm_t to mozilla_t through a binary labelled mozilla_exec_t), SELinux sets the AT_SECURE flag for the loaded application (in the example, mozilla/firefox). In other words, every time a domain transition occurs, the environment for this application is sanitized.

As you can imagine now the noatsecure permission disables the environment sanitation activity for a particular transition. You can do this through the following allow statement (applied to the above example):

allow sysadm_t mozilla_t:process { noatsecure };

if every domain transition for which this permission isn’t allowed would log its denial, our audit logs would be filled with noise. That is why the reference policy by default hides (dontaudit) these calls. But knowing what they are for is important, because you might sometimes come into contact with it, like I did:

>>> Installing (1 of 1) net-dns/host-991529
>>> Setting SELinux security labels
ERROR: ld.so: object 'libsandbox.so' from LD_PRELOAD cannot be preloaded: ignored.

This error message is when Portage (running in portage_t) wants to relabel the files that it just placed on the system through setfiles (which will run in setfiles_t). As this involves a domain transition, AT_SECURE is set for setfiles, but LD_PRELOAD was set as part of Portage’ sandboxing feature. This environment variable is disabled, and the loader warns the user that it cannot preload libsandbox.so.

Although we can just set noatsecure here, it would open up a (small) window for exploits (although they would need to be provided through Portage, because when a user calls Portage, a domain transition is done there as well so the user-provided environment variables are already sanitized by then). By not allowing noatsecure, we are disabling a few functionalities provided by the libsandbox.so library for the file labeling activity (this is very important to understand: it does not disable the sandboxing for the builds and merges, only for the file relabeling). As we already run setfiles in its own, confined domain, I believe that we are best served by keeping the secure environment sanitation here. That does mean that the warning will stay as we cannot control that from within SELinux.

If you want to allow noatsecure here, create a simple module and load it:

~# cat > portage_noatsecure.te << EOF
module portage_noatsecure 1.0;
require {
  type portage_t;
  type setfiles_t;
  class process { noatsecure };
}
allow portage_t setfiles_t:process { noatsecure };
EOF
~# checkmodule -m -o portage_noatsecure.mod portage_noatsecure.te
~# semodule_package -o portage_noatsecure.pp -m portage_noatsecure.mod
~# semodule -i portage_noatsecure.pp
Posted in Hardened, SELinux | 1 Comment

cvechecker 3.0

I’m pleased to announce the immediate availability of cvechecker 3.0. It contains two major feature enhancements: watchlists and MySQL support.

watchlists allow cvechecker to track and report on CVEs for software that cvechecker didn’t detect on the system (or perhaps even isn’t installed on the system). You can use watchlists to stay informed of potential vulnerabilities in software used at work on servers where you are not allowed (or do not want) to run cvechecker on. To use watchlists, create a text file containing the CPE identifiers for the software that you want to watch out for, and add it to the database:

~$ cat watchlist.txt
cpe:/a:microsoft:excel:2003:::

~$ cvechecker -d -w watchlist.txt
Adding CPE entries
  - Added watch for cpe:/a:microsoft:excel:2003:::

The second major feature is support for MySQL. This is the first server-oriented RDBMS that cvechecker supports (earlier versions worked with sqlite only) although sqlite support remains available as well. I hope to extend the number of supported databases in the future (say PostgreSQL, Oracle, SQL Server, …). With support for server RDBMSes came of course the requirement that multiple cvechecker clients are able to use the same server (as the CVE and CPE data itself can be shared). With the 3.0 release, this is supported as each client now “adds” to the data both his hostname as well as an (optional) user defined value (which can be anything you like). If unset, this user value is set to the hostname, but you can use things like the systems’ serial ID or asset ID.

I’m hoping all users have fun with it – I know I have while writing it. Feedback, remarks, feature requests, bugs and other criticism is always very much appreciated.

Posted in cvechecker | Leave a comment