It’s no surprise that virtually all computers nowadays use either Linux, Windows, or a fork of the former. But, why? Are we already at a point where operating systems can no longer be improved?
Current flaws
No. Those operating systems are obsolete. They all are a pile of junk stuck together, for many reasons. We’ll discuss them one by one.
Monolithic kernel
Windows is a huge pile of components, many of them running on kernelspace (I don’t think I need to explain why this is a bad idea).
Linux might not seem like a monolithic kernel, specially after considering Windows, but it still is. Many components are still on kernelspace, running as kernel modules. As a result of bad design decisions, FUSE (filesystem in userspace) was created. If the file system had been a userspace thing from the beginning, this wouldn’t have happened.
Users
You might be familiar with the linux user system. You usually have a root
user and your own “unprivileged” user. However, if you run cat /etc/passwd
you’ll find a few more. That’s because some programs decide they want their own user. As an example, I have dbus
, systemd-coredump
, systemd-network
, dhcpcd
, qemu
, git
, polkitd
, and many more.
The reality is that most use cases of the user system are not human users. Often, it’s used in the lack of a better sandboxing system.
Sandboxing
There is no mainstream OS that has good sandboxing (half-decent at best). One option would be giving the initial process full permissions. Then, every process would inherit the permissions from its parent. Obviously, changing the parent of a process wouldn’t be allowed. There would only be syscalls for revoking permissions to the process itself (not other processes).
Thus, in a fork
/exec
design, a process could create another one by:
- Forking the process, creating an identical process, strictly as a child.
- In the child process, revoking itself some permissions
- In the child process, replacing the current process executable with the desired one
I/O
Linux has many different ways to interact with hardware, with little to no consistency.
Kernel-space drivers
Hot take: device drivers shouldn’t run on kernel-space. Just think about it. Just because a piece of code needs access to I/O doesn’t mean it should have access to the entire computer.
Instead, following the described design, I/O operations could be done via syscalls. So, the initial process would spawn all device drivers, revoke itself most permissions, and then spawn user processes.
Flaws of the proposed design
The proposed design is not perfect, though. One of the main flaws is the speed of device drivers. Context switching is expensive, so I/O operations would be much slower.
Another flaw is that, if a new permission is introduced and programs are not updated accordingly, undesired permissions could be passed down to children. One solution would be to have a “maximum OS version” field in executable files. So, if the current OS version is greater than specified in the executable, the OS will refuse to run it.