Fixing the Desktop Linux Security Model
Whonix is a security, privacy and anonymity focused Linux distribution. Recently, we’ve been focusing a lot on important security hardening measures and fixing architectural security issues within the desktop Linux security model. Any Linux distribution can be affected by these issues.
There is a common assumption that Linux is a very secure operating system. This is very far from the truth for various different reasons. Security guides aren’t a solution either.
There is no strong sandboxing in the standard desktop. This means all applications have access to each other’s data and can snoop on your personal information. Most programs are written in memory unsafe languages such as C or C++ which has been the cause of the majority of discovered security vulnerabilities and modern exploit mitigations such as Control-Flow Integrity are not widely used.
The kernel is also very lacking in security. It is a monolithic kernel written entirely in a memory unsafe language and has hundreds of bugs, many being security vulnerabilities, found each month. In fact, there are so many bugs being found in the kernel, developers can’t keep up which results in many of the bugs staying unfixed for a long time. The kernel is also decades behind in exploit mitigations and many kernel developers simply do not care enough.
On ordinary desktops, a compromised non-root user account which is member of group
sudo is almost equal to full root compromise as there are too many ways for an attacker to retrieve the sudo password. Usually, the standard user is part of group
sudo which makes this a massive issue and makes a sudo password almost security theater. For example, the attacker can exploit the plethora of keylogging opportunities such as X’s lack of GUI isolation, the many infoleaks in /proc, use LD_PRELOAD to hook into every process and so much more. Even if we mitigate every single way to log keystrokes, the attacker can just setup their own fake sudo program to grab the user password.
Due to this, the Whonix project has been investing a lot of time into developing proper security measures to help fix these issues.
The kernel is the core of the operating system and has many security issues as discussed above. The following are details about our efforts to improve kernel security.
hardened-kernel consists of hardened configurations and hardening patches for the Linux kernel. There are two kernel configs, hardened-vm-kernel and hardened-host-kernel. hardened-vm-kernel is designed specifically for virtual machines (VMs) and hardened-host-kernel is designed for hosts.
Both configs try to have as many hardening options enabled as possible and have little attack surface. hardened-vm-kernel only has support for VMs and all other hardware options are disabled to reduce attack surface and compile time.
During installation of hardened-vm-kernel, it compiles the kernel on your own machine and does not use a pre-compiled kernel. This ensures the kernel symbols in the compiled image are completely unique which makes it far harder for kernel exploits. This is possible due to hardened-vm-kernel having only VM config options enabled which drastically reduces compile time.
A development goal is that during installation of hardened-host-kernel, the kernel is not compiled on your machine but uses a pre-compiled kernel. This is because the host kernel needs most hardware options enabled to support most devices which makes compilation take a very long time.
The VM kernel is more secure than the host kernel due to having less attack surface and not being pre-compiled but if you want more security for the host, it is recommended to edit the hardened host config, enable only the hardware options you need and compile the kernel yourself. This makes the security of the host and VM kernel comparable.
These kernels use the linux-hardened kernel patch for further hardening. The advantages of this patch includes many ASLR improvements, more read-only kernel structures, writable function pointer detection, stricter sysctl configurations, more sanity checks, slab canaries and a lot more.
We are also contributing to linux-hardened and adding more hardening features. Our contributions include disabling TCP simultaneous connect, restricting module auto-loading to
CAP_SYS_MODULE, Trusted Path Execution (TPE), restricting sysfs access to root, restricting
perf_event_open() further to deny even root from using it and many more in the future.
security-misc (wiki) enables miscellaneous security features for better kernel self-protection, attack surface reduction, entropy collection improvements and more. It doesn’t just harden the kernel but also various other parts of the operating system. For example, it disables SUID binaries (experimental, soonish default) and locks down root user access to make root compromises far harder. It also uses stricter mount options for various filesystems and stricter file permissions.
Linux Kernel Runtime Guard (LKRG)
Linux Kernel Runtime Guard (LKRG) is a kernel module which performs runtime integrity checking of the kernel and detection of kernel exploits. It can kill entire classes of kernel exploits and while LKRG is bypassable by design, such bypasses tend to require more complicated and/or less reliable exploits.
tirdad is a kernel module that aims to prevent TCP Initial Sequence Number (ISN) based information leaks by randomizing the TCP ISNs. These issues can be potentially catastrophic for anonymity and long-running cryptographic operations.
User space is the code that runs outside of the kernel such as your usual applications.
apparmor-profile-everything is an AppArmor policy to confine all user space processes, including even the init. This allows us to implement strict mandatory access control restrictions on all processes and have fine-grained controls over what they can access.
This is implemented by an initramfs hook which loads an AppArmor profile for systemd, the init.
apparmor-profile-everything gives us many advantages by limiting what an attacker can do if they compromise parts of the system. The benefits are not just for user space though. We can also protect the kernel to a great degree with this by blocking access to dangerous capabilities that allow kernel modification such as
CAP_SYS_RAWIO, having fine-grained restrictions on kernel interfaces known for information leaks such as
/sys and so much more. apparmor-profile-everything even allows us to deny access to the
CAP_NET_ADMIN capability which prevents even the root user from leaking the IP address on the Whonix Gateway (it would now require a kernel compromise).
With apparmor-profile-everything, the only reasonable way to break out of the restrictions is by attacking the kernel which we make much harder as documented above. The root user cannot disable the protections at runtime as we deny access to the required capabilities and files.
sandbox-app-launcher is an app launcher that starts all user applications in a restrictive sandbox. It creates a separate user for each application ensuring they cannot access each other’s data, runs the app inside a bubblewrap sandbox and confines the app with a strict AppArmor profile.
Bubblewrap allows us to make use of kernel sandboxing technologies called namespaces and seccomp. Namespaces allow us to isolate certain system resources. All apps are run in mount, PID, cgroup and UTS namespaces. Fine-grained filesystem restrictions are implemented via mount namespaces and AppArmor. Seccomp blocks certain syscalls which can greatly reduce kernel attack surface among other things. All apps by default use a seccomp blacklist to block dangerous and unused syscalls. Seccomp isn’t just used for bluntly blocking syscalls either. It’s also used to block unused socket families by inspection of the
socket() syscall, dangerous ioctls such as
TIOCSTI (which can be used in sandbox escapes),
TIOCSETD (this can increase kernel attack surface by loading vulnerable line disciplines) and
SIOCGIFHWADDR (this can retrieve the user’s MAC address which is a privacy risk) by inspection of the
ioctl() syscall and even strict W^X protections by inspection of the
shmat() syscalls. AppArmor is used to apply W^X to the filesystem and prevent an attacker from executing arbitrary code. Apparmor also gives fine-grained controls over IPC signals, dbus, UNIX sockets, ptrace and more.
It doesn’t just stop there. sandbox-app-launcher implements an Android-like permissions system which allows you to revoke certain permissions such as network access for any application. During installation of new programs, you are asked which permissions you wish to grant the application.
hardened_malloc is a hardened memory allocator created by security researcher, Daniel Micay. It gives substantial protection from memory corruption vulnerabilities. It is heavily based on the OpenBSD malloc design but with numerous improvements. Daniel Micay is a respected security researcher who has put a lot of work into security and is the creator of GrapheneOS (formerly CopperheadOS), linux-hardened and more.
Whonix installs hardened_malloc by default but it is not used much yet. In the future, we may preload it globally and use it for every application.
VirusForget deactivates malware after a reboot from a non-root compromise by restoring sensitive files. Without this, it’s possible for malware to easily create a persistent, system-wide rootkit by for example, modifying
~/.bashrc to hook into all user applications.
Verified boot ensures the integrity of the boot chain by verifying the bootloader, kernel and initrd with a cryptographic signature. It can be extended further and verify the entire base OS, ensuring all executed code has not been tampered with but this extension is unlikely to be implemented due to the layout of traditional Linux distributions.
All of our security features can be reverted by the user if they prefer freedom over security by choosing the necessary boot modes. This is not a security risk and attackers cannot abuse this as it can only be done with local access.
There is still a lot more work to be done and we need your help. Contributions would be greatly appreciated. The implementation of sandbox-app-launcher, packaging of hardened-kernel and verified boot are some of our main issues. Qubes support for hardened-kernel, apparmor-profile-everything, LKRG, tirdad and security-misc’s boot parameters are missing. Also see the list of open tasks.
Edit by Patrick: