Hey, all,
While we're waiting for a patch to be released, just a small review of what it's about and what to do to fix it.
On systems where Xorg binary is deployed setuid-root, and due to insufficient input checking, it is possible to exploit the program to obtain unauthorised privilege escalation ability.
This is primarily due to two options, one to specify module path (but that one is more difficult to exploit, because one would have to have a correctly written and compiled Xorg loadable module matching the version of the binary used in the attack), and one to specify the log file path.
The log file attack is indeed very straightforward: (first back up and then) overwrite the shadow file with an entry that effectively removes the root user's password and use "su - root".
$ sudo cp /etc/shadow /etc/shadow-backup $ cd /etc $ Xorg -fp 'root:::0:99999:7:::' -logfile shadow :1 [switch back to a usable VT - mind, you won't be able to login except as root after overwriting shadow] $ su - root # boom
This is another one of the cases where correct system configuration can prevent this sort of thing from happening, First of all, there is absolutely no reason to have Xorg present on a server and this recent exploit only goes to reinforce this statement, but on systems where one absolutely can not avoid that, there are two options to avoid the above exploit:
Because the second approach is much simpler and it allows for overall improvements in security, I'll quickly outline why the above is possible and what the correct approach to fix it is.
In SELinux, both files and processes have security labels, and a security policy defines what actions on behalf of a process with a certain label (or as we call it, scontext) are possible towards a file with a certain label (or tcontext).
For processes to be able to change their label (for example, systemd has a label of init_t whereas sshd, which is started by systemd and would normally inherit its label, has a label of sshd_t), a transition has to be defined in the security policy.
This is all true in Xorg case as well, as Xorg actually does get a special context type of xserver_t upon startup, because there is a transition rule in the targeted policy that says any executed file with the file type of xserver_exec_t should become an xserver_t type of process.
However, we are only looking at the context type here. The role and user components of the process label are not subject to this transition, and if an unconfined user executes the Xorg binary, the process effectively remains unconfined:
$ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ Xorg :1 & $ ps -q $(pgrep Xorg | tail -n1) -Z LABEL PID TTY TIME CMD unconfined_u:unconfined_r:xserver_t:s0-s0:c0.c1023 5561 tty2 00:00:00 Xorg
So the clear answer to this problem is that interactive users should be confined by default, which they are not (notice the line starting with __default__):
# semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 *
If we want to have users confined by default, the SELinux User's and Administrator's Guide states there are several SELinux users available:
# semanage user -l Labelling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles guest_u user s0 s0 guest_r root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r sysadm_u user s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r unconfined_r unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r xguest_u user s0 s0 xguest_r
Each of the above SELinux users is a bearer of one or more security roles that determine what kinds of actions they can perform, and there are also several boolean settings you can tune to further restrict or relax certain things they are allowed to do.
The immediate thing to do in the Xorg case is to change the default isolation level of interactive users to something like user_u (with the added note the allowable MLS/MCS Range for user_u is only s0, so that needs to be changed as well):
# semanage login -m -s user_u -r s0 __default__
That's all!
If you want to learn more about SELinux, I invite you to have a look at the excellent SELinux Coloring Book by Dan Walsh and Máirín Duffy for the basics. If you want to learn about the icing on the cake, we have recently released a new course called Red Hat Security: Linux in Physical, Virtual, and Cloud that talks about SELinux among other things (it is very much recommended to have RHCE certification or equivalent skills because this really is an advanced course).
Good luck securing your systems!
Red Hat
Learning Community
A collaborative learning environment, enabling open source skill development.