by Joshua Branson — April 17, 2024
I have talked about OpenBSD before in this blog, and I recently
watched a talk by OpenBSD's leader Theo de Raadt about pledge ()
and
arc4random()
. He described OpenBSD's design philosophy so well, that
I wanted to write it down. You should definitely take some time to
hear Theo speak. He's entertaining, and his talks are super awesome!
So a long time ago (early 90s ?), a cracker (1) broke into Theo's OpenBSD's syslog. This got Theo to examine OpenBSD's source code to fix any lingering bugs, and he found a lot. He realized that trying to constantly examine source code to prevent bugs is a never ending process. He wanted to ensure code quality got better over time. He envision an operating system that that enforced code correctness like the below ASCII art shows.
__________________________
| Poorly written programs |
| crash on OpenBSD. |
| ---------------------- |
| | Correctly written | |
| | programs run well | |
| | on OpenBSD. | |
| ---------------------- |
---------------------------
He wondered if he could create features to slightly narrow the things that applications could do. When poorly written programs run on OpenBSD, they crash in deterministic ways, but correct programs work just fine. Theo also made sure that "mitigations", or checks to ensure a program's correctness, cannot be turned off on OpenBSD. If a user or a project manager has a problem with an application not working on OpenBSD due to a toggleable security feature, then the user or project manager will just turn off the feature. So to ensure that programs abide by the mitigations, OpenBSD enforces their security policies.
OpenBSD also makes it easy to use their security features. If they introduce a policy that is manatory, they try to make the API easy to use. If you create a security policy that is hard for the programmer to use, then the security policy won't be used.
When OpenBSD creates a new mitigation, their application porters port
3rd party software packages to OpenBSD. Typically these changes find
their way into the upstream packages. What's awesome is that usually
other operating systems start to use OpenBSD mitigations on their
systems 5 years after OpenBSD introduced them. Windows, Mac, and
Linux applications all benefit from the strict standards that OpenBSD
creates. Theo's talks gave two examples for this: pledge ()
and
arc4random ()
.
Here's a question for you. How do you get random data? Well you read
/dev/random
of course. Simple. Easy. Done. That used to be how
things were handled. Apparently reading from /dev/random
has some
limitations that Theo mentioned. Can you read from /dev/random
inside the kernel? Inside a library? In your libc? Reading from
/dev/random
is not perfect. Theo wanted to make something better.
OpenBSD created arc4random ()
as a better source of entropy. It is
a C function that almost any application can call (even the kernel),
most of the time. This lets many applications, libraries, etc. easily
use random numbers. What's surprizing to me is that many operating
systems use arc4random ()
or a function like it, so that more
applictions can easily request random data. This function (or one
like it) exists on your Android phone, iPhone, iMac, and sort of on
Linux thanks to OpenBSD.
What's pledge ()
? Oh ho, let me tell you! Let's take a look at a
typical program.
int main () {
initialize_stuff();
for (;;) {
;; let's run the program
}
}
Most programs have an initialization phase followed by a loop, in
which the application runs. The OpenBSD team realized that the
initialize phase uses most of the system calls. After the initialize
phase, the program typically needs less system calls. OpenBSD's
pledge ()
was created in response to this pattern present in most
programs.
pledge ()
is a security call, by which an application tells the
kernel, "I pledge to only do these things and no other." For example,
"I pledge to only output text". Or "I pledge to only access the
internet and output text." If the application tries to do something
that it has pledged not to do, then OpenBSD kills the application.
A really interesting blog post that talks about this is at justine's blog.
After watching two of Theo's talks, I am fairly convinced that his design goals are slowly working to make all POSIX operating systems more correct and secure. I used to dual boot Guix System and OpenBSD, but unfortunately my spare SSD busted. So for now I am only using Guix System. I personally prefer to use Guix System for my linode server (that powers this blog), because Guix makes it easy to manage servers.
I wish that the Guix developers could one day create Guix OpenBSD
System, but I have been told that Guix System assumes your libc is
glibc
and that OpenBSD cannot currently make isolated build
environments as well as Linux can. Also fun fact OpenBSD is not
currently working on reproducible builds. :)
My two only minor complaints with OpenBSD currently are:
- I wish OpenBSD supported Wayland. This may happen in 6 months to a year. Fingers crossed.
- A better filesystem: OpenBSD's FFS (fast file system) works, but it is possible to lose data in a crash. Filesystems are really hard to get right. Kent Overstreet has been working on bcachefs for almost a decade now, and it might soon become one of Linux's best filesystems (my opinion), so I don't blame OpenBSD for not trying to create a new next generational filesystem. Anybody want to spend 10 years of their life creating an awesome filesystem that will probably only work well on OpenBSD? One might be able to port HammerFS to OpenBSD, and a basic read-only port does exist.
If you want to try OpenBSD, give it a shot! It works really well on most lenovo laptops and most desktop machines.
- Nerdy computer people like me use the word "hacker" to mean someone who builds computer programs, and a "cracker" is someone who breaks into computer systems.