Hacker News new | ask | show | jobs
by tptacek 1345 days ago
The overwhelming majority of NTP deployments (by device count) don't benefit from any of the complexity or flexibility of chrony and ntpd, but do suffer from the memory-unsafety of those programs, and pass that unsafety on to the rest of us. The case for a memory-safe 80%-use-case NTP server is very strong.
2 comments

> the memory-unsafety of those programs

How do you know they are unsafe? Have they been audited and memory un-safety been found? I don't understand why the Rust community automatically assumes there are always memory safety issues with C, for example. I get that it's possible to write unsafe programs in C, but not all programs are automatically unsafe just because they are written in C.

I need to do more research, because I don't actually trust that just writing a program in Rust will result in total memory safety, so these are actually questions I want answers to, not just me trying to attack Rust or anything. Thanks!

It's not just the Rust community. I don't especially like Rust, but I fully buy into the argument that code written in memory-unsafe languages is materially less safe than code that is. There are plenty of memory-safe options, and rewriting software to be memory safe --- especially when there's a clear, simple common case to seize on --- is a positive step for Internet safety.
I totally get that, but my stance on the matter is that some of the software we're talking about is just as memory safe as a new Rust rewrite because it doesn't do anything unsafe, but the rewrite could introduce other bugs and differences that could break things.

I would say I don't stand on the side of "rewrite nothing", but I'm more of a realist here, in that we absolutely cannot "rewrite everything" perfectly in a memory safe language, and we should first determine if a particular tool should be rewritten in a memory safe language by doing some analysis and testing on that tool.

Certainly, even though I know no Rust and am not an expert in memory safety, I would say that in the future we should try not to write totally new software in memory unsafe languages, but I'm not everyone so I can't make that rule and ensure it sticks.

Your stance, that audited C code is "just as memory safe" as new Rust, is wildly outside of the mainstream of software security. You're entitled to your opinions, but you're unlikely to find many qualified people to dive into a debate as unproductive as that. Plenty of carefully audited C code has later been found to have terrible flaws, and likely will again in the future.
Well then I guess "mainstream of software security" needs to do a better marketing job to explain to dumb programmers like me why I should be using memory safe programming languages!

Seriously, I would love to see a succinct explanation for the "rewrite everything" philosophy, but it seems religiously dogmatic to me so far and has done the opposite of convince me to use Rust (or another memory-safe language).

On the other hand, the "statically typed language" community has done a great job of convincing me that I should be using statically typed programming languages by showing many examples of where typing would help me in my day to day work, and now I like using Go a lot and I avoid tons of issues I had with Python in the past.

No, they don't. Not in this case, at least. They can just build better software, and it will get adopted. You're writing Go already, so I'm not sure why anyone would want to burn time in pointless debates about this stuff. Carry on! You're already doing it right.
The irony of you calling others dogmatic in this conversation is a cue for me to stop reading it, I guess.
What you're doing is just FUD bordering on some kind of weird concern trolling.

Gonna blow your mind when I tell you every single coreutil on my system is built with Rust and moreover nearly every program on my system was BUILT with that Rust-built coreutils.

Amazingly emulating some existing program behavior in Rust is easier than writing safe C! Who would've guessed? (besides eeveyone else watching and betting on Rust for the past 8 years)

>How do you know they are unsafe? Have they been audited and memory un-safety been found?

Security vulnerabilities caused by memory safety errors can be an indication.

The number of CVEs doesn't necessarily indicate the number of errors in the code, or whether or not something is secure, since there are a lot of factors at play. A project with many CVEs could be a good sign since it means people are actively looking for and reporting issues for example. Alternatively a project with few CVEs might have a ton of hidden bugs.

It's not a perfect measure for sure, but it can at least prove that there are real world memory safety bugs that can have disastrous effects if left unfixed.

https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ntpd

https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=chrony

For those that did not click on the link, that lists 11 CVEs for chrony and 68 for ntpd
FWIW, from those 11 chrony CVEs:

- 8 were found within the project itself (mostly by me)

- none are memory-safety issues in the NTP-specific code

- the last memory-safety issue is from 2015 and it was in the custom management protocol (exploitable only by authenticated users), which was since then greatly simplified and made stateless

The project now has an excellent fuzzing coverage, it was audited, and I'm quite confident there are no remotely reachable memory-safety issues. I'll buy you a drink if you find one :).

NTP as a network protocol is extremely simple. There is no complex data, almost everything has a constant length. A minimal server+client implementation can be written in a few hundred lines of code. I wrote one in Rust, but the reason was server performance, not security.

Most of the complexity related to NTP is on the client side, in the processing of measurements provided by NTP. I don't think the language matters much here. However, if major operating systems will start switching to services written in Rust, I don't see a reason why chrony couldn't be rewritten in Rust, first the small parts related to networking and later everything.

Thanks for actually showing me some concrete examples of my wrongness instead of just attacking my character like a few others here (not my main thread here, that was a great discussion).
This is so cringe, to have this conversation constantly continue to crop up on Rust safety discussions when it's built on such an obviously falsifiable premise.

What C project is safe, exactly? You imply that the default almost is churning out safe C, so what projects with "competent" coders is producing vulnerability-less C code bases? I'll not be holding my breath because everytime, there's never an answer. My favorite person who spouts this off has multiple projects that have segfaulted from C memory programming related bugs.

Maybe, like, validate the basics of Rust functionality instead of constantly just casting doubt and aspersions on something while offering really weak defenses of what you justhl happen to be conditioned to.

I'm just trying to understand why I would want to use Rust. You Rust people constantly act like dickheads anytime anyone asks questions like I did. If you all are so goddamn sure that it's the best way, then how about not acting like a total asshole to me and point me to some things I can read that will convert me?

You folks are the reason no one likes Rust people and Rust adoption is lower than it should be; try being human for once.

With all due respect, I don't know what I could possibly point you to. Rust is just a better language than C or C++. It eliminates many classes of bugs that are pervasive in those two languages. It's a true 10x advancement over mainstream languages of the past. It also has been getting plenty of traction all across the industry, from Facebook and Amazon to small startups and open source projects like the Linux kernel.
The overwhelming majority of NTP deployments should probably not be running NTP in the first place.
Why do you think so? Once you need to sync with some external source occasionally anyway, why not just run ntp continuously and be actually in sync all the time? (or why would it be better not to do that?)
NTP is insecure, and it fundamentally solves a different problem than the "I need a precise to a second timestamp to validate certificates and update my RTC" need of the majority of devices.
> NTP is insecure

That's vague. What do you mean specifically? Hostile nodes joining the pools? Any issues with the protocol? Something else?

Yes, the base NTP protocol is unauthenticated UDP. So, that's pretty insecure.

Properly configured, with sufficient upstream time servers, etc... it's still pretty robust against DoS attacks and evil maid attacks, so you'll have to do some work to trick clients into following your fake NTP server. And it will be hard to hide what you're doing while you do it.

It took a while, but I think we've actually solved that security problem with NTS. Now we just have to get the vendors and the community to support and deploy NTS widely.

The blog say the example use is certificate expiry check. I think this only need ~1 minute precision. You can do away with a weekly cron job.
That assumes your clock is running at a reasonable rate, and that the clock speed doesn't vary, etc....

The more your clock is skewed, the more often you need to check to see how badly it's skewed and apply whatever corrections are necessary.

That said, I'm a big fan of running SNTP as a client, where you don't need the full power of the NTP protocol. There's no sense running a full blown NTP client on most systems.

I like the idea of memory safety, but that's just one category of potential security vulnerabilities. If Rust can solve for that and also give me other benefits like higher speed, then I'm all for it. But you have to give me a lot of good reasons, or a hell of a good single reason, if you want me to toss out everything and replace it with Rust. And IMO, memory safety alone is not a good enough reason for most use cases.

LE certs are normally cycled days ahead, so you need only +/-1 day precision for that specific purpose. But the question was: if you need to sync from time to time anyway, why is staying in sync using ntp a thing we wouldn't want?