5

On a Fedora 18 machine, I have the following SELinux context as a regular user created during installation:

$ sestatus
SELinux status:                 enabled
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed

and

$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

I want to run a program with the confined selinux role user_r, instead of my current unconfined_r, so I create a new user with the confined SELinux user user_r:

# useradd -MN -Z user_u johndoe
# echo 'fubar' | passwd johndoe --stdin

Now, I open up a new tty and login as johndoe using agetty. It complains that /home/johndoe does not exist, but essentially, it logs me in. SELinux context:

$ id -Z
user_u:user_r:user_t:s0

user_u:user_r:user_t is perfect and what I want. But I would like to achieve this in a script already running as an unconfined_u and not as a fresh login. I tried with sudo:

If I use sudo -u, I get:

$ sudo -u johndoe id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Which means that the SELinux user doesn't change.

I also tried:

$ sudo -r user_r -u johndoe id -Z
sudo: unconfined_u:user_r:user_t:s0-s0:c0.c1023 is not a valid context
sudo: unable to execute /bin/id: Invalid argument

So, no luck there either.

So how can I transition from the unconfined_r role to user_r, using sudo or su (or anything else)?

3 Answers3

4

Have you tried the policycoreutils-sandbox solution? This is for exactly what you want. For example if you want to execute Firefox in a SELinux restricted environment (unfortunately, but for good reason, "sandbox" is only supported on Red Hat distributions):

/usr/bin/sandbox -X -t sandbox_web_t firefox

SELinux is set apart from other LSM-based MAC systems by its flexibility and customizability.

This allows you to do what you want, even if it does not make sense. One prerequisite is that you are aware of at least the basic principles and concepts.

There are a couple of things that need to be taken care of here:

  • the unconfined_u SELinux identity security identifier must be associated with the user_r SELinux role security identifier if you want the "unconfined_u:user_r" combination in a security context to be valid.

This can be done with:

semanage user -m -L s0 -r s0-s0:c0.c1023 -R "unconfined_r system_r user_r" -P user unconfined_u
  • The unconfined_r SELinux role security identifier must be allowed to be manually (via sudo in this case) changed to the user_r SELinux role security identifier.

This can be done by creating a simple policy module:

cat > myuser.te <<EOF
module myuser 1.0;
require { role unconfined_r, user_r; }
allow unconfined_r user_r;
EOF

checkmodule -M -m myuser.te -o myuser.mod
semodule_package -o myuser.pp -m myuser.mod
sudo semodule -i myuser.pp
  • Sudo needs to be told which SELinux type security identifier it should use together with the specified user_r SELinux role security identifier

    sudo -r user_r -t user_t id -Z

I believe i touched on all the consideration but i might have overlooked some and my example may have typo's. Refer to the manual pages for the commands i mentioned.

domg472
  • 41
2

While using MLS, your command

sudo -u johndoe id -Z

means that you are passing your role and type to sudo. You should use the command

sudo -r user_r -u johndoe id -Z

Also, if you tried to login with console or ssh you could also see the correct roles and types.

EDIT: I want to give some notes too. You can not change your context (id -Z) if there is not a valid transition. You will get error like

sudo: ... is not a valid context

For being root, firstly you should be in sudoers file and staff_u selinux user. For sudo, I like adding only myuser ALL=/bin/su for using sudo su -. After I did sudo su -, became root, I execute newrole -r sysadm_r to gain system admin rights. It is not surprising because sudo can not change role. As same as, before logging out I execute newrole -r staff_r to return my own role. After that I log out, otherwise shell hangs (valid context error).

1

That's quite tricky. I got something working trough a hack. First, write your script in a file. Then, use semanage fcontext to add a labelling rule. SELinux uses this label to apply confinment, somehow. In my example, I'm reproducing postgres context.

# semanage fcontext -a -s system_u -t postgresql_exec_t /absolute/path/to/my-script
# restorecon -v my-script

SELinux knows some transition. For exemple systemd runs in init_t and file labelled with postgresql_exec_t are transitionned in postgresql context. Thus, I wrote a oneshot systemd service to reuse that transition.

# /etc/systemd/system/multi-users.target.wants/my-script.service
[Unit]
Description=My Script
After=syslog.target
After=network.target

[Service]
Type=oneshot

User=postgres
Group=postgres

ExecStart=/usr/local/bin/cornac-selinux

Then, run it with systemctl

# systemctl start my-script.service
# journalctl -n 10 --no-pager
août 19 15:19:11 bernace-db0 cornac-selinux[14928]: + id                                                                                
août 19 15:19:11 bernace-db0 cornac-selinux[14928]: uid=26(postgres) gid=26(postgres) groupes=26(postgres) contexte=system_u:system_r:postgresql_t:s0                                                                                                                            

That's the best I can do so far, without writing a custom policy module.