As a fan of the SELinux
security framework that runs as part of Linux, I thought it would be a good
idea to improve my skillset in this area, and go beyond the basics.
Part of that is research, subscribing to
SELinux mailing lists, playing with test setups and, of course, reading what
others are saying via Google searches.
One, whilst going off at a tangent to my goal,
sparked my interest as all the posts I saw didn't have the answer. It was this
type of error:
libsemanage.validate_handler: MLS range s0-s1:c1,c3 for Unix user XXX
exceeds allowed range s0:c1,c3-s1:c1,c3 for SELinux user XXX
libsemanage.validate_handler: seuser mapping [XXX -> (XXX,
s0-s1:c1,c3)] is invalid
libsemanage.dbase_llist_iterate: could not iterate over records
The answer should be straightforward, and
relies on the fact that SELinux enforces mandatory access controls; aka stop
you doing stupid or bad things (or at least what policy states are stupid/bad
things), plus the tools stop stupid/bad configurations (again, at least what
the developers state are such).
We can look at three types of user concept
here. First, we have the traditional UNIX user as defined in /etc/passwd or your favourite password
backend. Secondly, we have the concept of an SELinux user, which is more akin
to a class or UNIX group. Finally, we have mappings which map the UNIX user to
the SELinux user, which themselves (can) specify ranges.
SELinux users are managed by semanage user, whilst the mappings are
managed by semanage
login.
If we map a UNIX user to a SELinux user, we are
stating that the UNIX user has a particular range of clearances to access and
do stuff on the machine. However, when we set up the mapping we can further
constrain the user, but cannot (shouldn't be able to) grant more than the base
SELinux user they are mapped to.
So, here's an example on one of my test boxes.
The test box is running the mls policy and is using
poly-instantiated directories of /tmp /var/tmp and $HOME based on the context (i.e. we can only see a
home area or temp area commensurate to our current level.
First, lets create an SELinux user of devuser_u which has the standard user
role of user_r:
[root@centos-7-2-t1 ~]# semanage user -a -R user_r -r s0-s1:c1,c3
devuser_u
[root@centos-7-2-t1 ~]# semanage user -l
Labelling MLS/ MLS/
SELinux User Prefix MCS Level
MCS Range SELinux Roles
devuser_u user s0 s0-s1:c1,c3 user_r
…
Now
let's create a user that is of that type:
[root@centos-7-2-t1 ~]# useradd -m -Z devuser_u dev1
[root@centos-7-2-t1 ~]# semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__
user_u s0 *
dev1
devuser_u
s0-s1:c1,c3 *
…
Now lets say that we wish for the user to be
able to access a new category (compartment) of c8. We may state that we do this with the
mapping, but as this user is an SELinux user of devuser_u this isn't going to work:
[root@centos-7-2-t1 ~]# semanage login -m -r s0-s1:c1,c3,c8 dev1
libsemanage.validate_handler: MLS range s0-s1:c1,c3,c8 for Unix
user dev1 exceeds allowed range s0-s1:c1,c3 for SELinux user devuser_u
libsemanage.validate_handler: seuser mapping [dev1 ->
(devuser_u, s0-s1:c1,c3,c8)] is invalid
libsemanage.dbase_llist_iterate: could not iterate over records
ValueError: Could not commit semanage transaction
Instead we either need to create a new SELinux
user (and map the unix user to it) or modify the existing one. So, lets modify
the existing one so that it includes this new category:
[root@centos-7-2-t1 ~]# semanage user -m -r s0-s1:c1,c3,c8
devuser_u
[root@centos-7-2-t1 ~]# semanage user -l
Labelling MLS/ MLS/
SELinux User Prefix MCS Level
MCS Range SELinux Roles
devuser_u user s0 s0-s1:c1,c3,c8 user_r
…
Cool, that worked. Note that this does not
update the individual mappings.
[root@centos-7-2-t1 ~]# semanage login -l
Login Name SELinux
User MLS/MCS Range Service
__default__
user_u s0 *
dev1
devuser_u
s0-s1:c1,c3 *
…
So, lets do that.
[root@centos-7-2-t1 ~]# semanage login -m -r s0-s1:c1,c3,c8 dev1
[root@centos-7-2-t1 ~]# semanage login -l
Login Name SELinux
User MLS/MCS Range Service
__default__
user_u s0 *
dev1 devuser_u s0-s1:c1,c3,c8 *
…
So now all is well.
Providing the MLS/MCS range of the SELinux user
is a superset of the range an individual user has, then you shouldn't have a
problem.
A side note, I have found it is occasionally
possible to sometimes modify the SELinux user to no longer be a superset; but
then all other modifications against that user breaks until you fix it (i.e.
make it a superset, then clear the categories or sensitivities you wish to
remove from the member UNIX user mappings, then update the SELinux user); a bug
perhaps.
No comments:
Post a Comment