In this talk on privilege separation, Theo de Raadt explains that OpenBSD's ntpd has a master process which calls settimeofday()
, a DNS process responsible for querying DNS servers, and an NTP protocol process which is responsible for speaking UDP to NTP servers. He has this to say about the DNS process:
The other thing we've got is a separate DNS servicer process, cause we wanted to be able to do DNS, but we didn't want the master process to do it because DNS libraries sometimes have bugs, and we didn't want the internet speaker to do it because... it's... it just didn't make sense.
Let's assume that pledge doesn't exist (this design predates it, as I understand it). Obviously this design is pretty pointless on its own, as if the network-facing service is compromised the attacker has root on the system. Therefore, the master process will fork both subprocesses, which will immediately drop privileges to nobody
or something. That way, if there's a security bug in either the DNS library or the NTP code, the attacker doesn't have write access to system file, home directories, etc.
That all makes sense to me. However, what I don't understand is why the separation between the DNS and UDP processes is useful. It doesn't matter which one is compromised; the attacker is running as the same user either way. You could put the DNS process in e.g. a nobody2
user, but even then, nobody2
will be just as unprivileged as nobody
.
With pledge, the benefit is obvious since e.g. the DNS process can pledge that it will only make DNS queries, which will be pretty damn useless for an attacker. However we're assuming that pledge isn't a factor since this design was introduced before pledge.
Is there any security benefit to the three-process ntpd design that I'm missing? Or was it just a design decision unrelated to security (perhaps considering the possibility of a future pledge-like system)?