[HN Gopher] A Memory Safe NTP Implementation
___________________________________________________________________
A Memory Safe NTP Implementation
Author : SGran
Score : 74 points
Date : 2022-10-11 16:52 UTC (6 hours ago)
(HTM) web link (www.memorysafety.org)
(TXT) w3m dump (www.memorysafety.org)
| yuuta wrote:
| I don't see the whole point. It's like creating yet-another-ntp-
| implementation while other well-known implementations are known
| to be working good and safely on billions of devices.
|
| It is easier to report a security issue to ntpd or chrony instead
| of creating a new one.
| tptacek wrote:
| 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.
| stefan_ wrote:
| The overwhelming majority of NTP deployments should probably
| not be running NTP in the first place.
| viraptor wrote:
| 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?
| ok_dad wrote:
| > 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!
| tptacek wrote:
| 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.
| ok_dad wrote:
| 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.
| bqmjjx0kac wrote:
| Out of curiosity, would you ever support rewriting an existing
| memory-unsafe program in a memory-safe language?
| Thaxll wrote:
| staticassertion wrote:
| It's a networked, privileged process. If my goal were "try to
| ensure that more of my OS is memory safe" I'd probably start
| somewhere similar.
|
| A lot of this post is specifically addressing the justification
| for this work so idk, I'd suggest responding to that directly.
| bsder wrote:
| NTP takes in untrusted input from the net, does complex
| processing on it, and requires the ability to do something
| administrative on your system (adjust the time).
|
| This gives NTP a lot of attack surface and makes it a likely
| vector for compromise.
|
| Rewriting NTP in _any_ language safer than C /C++ is likely to
| be a good idea.
| kelnos wrote:
| > _a rewrite for the sake of safety is not sufficient imo_
|
| I would disagree; I think a rewrite for the sake of safety,
| especially when we are talking about a piece of server software
| that deals with untrusted clients, is often worth it.
|
| Certainly it isn't always: rewriting huge, complex pieces of
| software for the sake of _anything_ (including safety) may just
| not be justifiable. Like, sure, maybe the Linux kernel would
| benefit from a rewrite in Rust, but I don 't think that would
| be a good idea.
|
| NTP is a fairly small protocol, and at least the server portion
| -- where I'd be the most worried about memory safety issues --
| can be implemented in Rust without too much difficulty. As I
| understand it, NTP clients can be a bit more complicated. But I
| still expect they're much less complicated than many other
| types of clients.
|
| > _Are they going to maintain that forever and push Linux
| distro and the industry to move to that new solution?_
|
| Why not? That's how open source Linux software works. Someone
| builds it, and if there's enough interest, it gets adopted, and
| attracts new contributors and maintainers over time. If there
| isn't enough interest, it withers away.
|
| That may not be your idea of the best use of your time (and I
| might agree), but who are we to tell others what to do with
| their time?
| jeffbee wrote:
| There's no reason to believe there isn't some vulnerability
| lurking in chrony, which is a highly privileged process. These
| are exactly the starting points I would hope for.
|
| On the other hand, the statement that they did not study chrony
| because they couldn't understand it does not exactly fill me
| with confidence.
| kelnos wrote:
| To be fair, chrony, at least on my system, is not running as
| root. I'm not sure what mechanism it uses to set the system
| time, whether it's capabilities, or a setuid helper program,
| but I think it's safe to assume that, if compromised, the
| only malicious thing that it could do would be to set my
| system time to something incorrect. Which isn't nothing, but
| also isn't much, either.
| tptacek wrote:
| _Please don 't comment about the voting on comments. It never
| does any good, and it makes boring reading._
|
| https://news.ycombinator.com/newsguidelines.html
| bogota wrote:
| They are justifying the rewrite by saying that it is memory
| safe. I don't think its a bad goal but if they don't do the
| work to maintain and package these for distros it wont make it
| very far.
|
| However im always surprised by how many people are fanatics of
| rust and they do contribute a lot to packaging at least for
| Gentoo which is my daily driver. I could see a lot of these
| taking off if it does show a reduction in attack surface and it
| works seamlessly as a replacement for existing solutions
| hopefully not forcing a new config on everyone.
| akira2501 wrote:
| Doesn't Rust just panic and abort on runtime memory errors?
|
| So, we maybe get memory security, but we seemingly do nothing
| for DoS. Isn't that a large attack vector for NTP, given it's
| primary utility in other protocols?
| black_puppydog wrote:
| No, rust avoids most memory errors by proving _at compile
| time_ that they don 't exist. That's why it forces you to
| write code with lifetime annotations and such, so that thst
| proof becomes feasible.
|
| I say "most" because it also allows you to get out the
| footguns, meaning you can sidestep this proof mechanism.
| But you do that by declaring a block/function as "unsafe",
| so if you do find a memory bug, you know exactly where to
| start your search.
| Veliladon wrote:
| > Doesn't Rust just panic and abort on runtime memory
| errors?
|
| Technically yes if you directly access an index that's OOB
| but stuff like Vecs and Arrays have the get and get_mut
| methods which allows you to try to retrieve an element (or
| slice). If the element is in bounds you get a Some<T> with
| a reference to the element (or slice) and if it fails it'll
| return an Error type which can be handled rather than
| panicking out.
|
| It's not even slower to use the .get method rather than
| direct indexes because attempts to access indexes directly
| are implemented as .get.unwrap()
| staticassertion wrote:
| That's right, DoS in Rust is still a thing you can have.
| But it's no worse than in memory unsafe languages, since
| memory unsafety can also lead to DoS (and in a much worse
| way - there are methods for managing panics, managing
| segfaults is much harder).
| steveklabnik wrote:
| Rust the language doesn't know anything about heap
| allocation, so in a strict sense, no.
|
| The standard library provides a number of APIs that abort
| on allocation failures, yes. There are currently nightly-
| only APIs for some of them to return Result instead, and
| they'll hit stable eventually. You could also not use them
| if you don't want that behavior.
| wyager wrote:
| People find vulnerabilities in old software all the time.
| mro_name wrote:
| expat, sigh. openssl, sigh again.
| manfre wrote:
| > Another benefit of Rust is that we can use its standard library
| and package ecosystem, so our NTP implementation is much smaller
| (hence easier to validate) than the alternatives
|
| It might be easier to validate the code in their repo, but I feel
| like they are ignoring the effort that would be needed to
| validate all of the very large number of dependencies.
| brundolf wrote:
| Most of the dependencies I see listed in this project are
| upstanding, household-name crates. Personally I'd feel more
| confident using those (which have many other eyes on them) than
| maintaining custom in-house implementations of complex (but
| standard) building-blocks
| staticassertion wrote:
| If their major concern is memory unsafety it's a lot easier.
| Most dependencies don't use any unsafe, and instead there's
| usually just a few libraries pulled in across them that do. One
| of the best parts of auditing rust (for memory unsafety) is
| that you can just "grep for unsafe" and know exactly where to
| start.
| raggi wrote:
| What is the most fascinating thing you learned when you read
| ntpd's configure script? What is the most interesting thing you
| learned reading glibc?
|
| Were you at all concerned when you discovered that the sources
| come from http-only servers and only have un-signed md5's for
| checksums?
|
| Did you find the support for HP-UX distracting?
| strangemonad wrote:
| There is a bunch of well funded work to tackle validating
| various aspects of rust, the std library, and ecosystem. For
| example rust-belt led by Derek Dryer https://plv.mpi-
| sws.org/rustbelt/
| nathas wrote:
| I'm really looking forward to the client implementation. I worked
| on a Rust NTP server where I used to work. It was truly faster
| than ntpd or chrony, which is a meaningful benefit when you're
| talking about something that sends out data about clocks and
| time.
|
| Unfortunately the server is relatively _easy_ to build. The
| client, however, is where a LOT of the intelligence and
| difficulty lies.
| jandrese wrote:
| The tricky part isn't the protocol, it's all of the interfaces
| with weirdo hardware clocks. Even just parsing GPGGA messages
| from a serial port can be tricky when you're trying to keep the
| timing tight.
| tptacek wrote:
| There is immense value in replacing simple NTP deployments,
| which don't interface with weirdo hardware clocks, with a
| memory-safe alternative; those simple deployments dwarf the
| weird ones. It is fine (good, even) for there to be multiple
| viable implementations of NTP, fit for different purposes.
| infamouscow wrote:
| It's unclear why Rust was chosen over OCaml or Haskell.
| mtlmtlmtlmtl wrote:
| It's pretty obvious actually. They want memory safety and
| predictable, good performance. Rust is the goto language for
| that in sysdev today. Go is a much better candidate than the
| ones you mention, but there are legitimate reasons to want to
| avoid GC.
|
| Additionally, the intersection of people who are interested in
| working on low level system daemons and people who prefer
| Haskell/OCaml must be pretty small compared to Rust.
| infamouscow wrote:
| mtlmtlmtlmtl wrote:
| Performance being important in system development is pretty
| much a given, and doesn't necessarily even need to be
| mentioned. You could argue that systems software is well
| defined as software where security, performance, and
| stability are more important than all other concerns.
|
| I think the fact that your comment didn't elaborate is why
| you're being downvoted, not for asking questions. It can be
| interpreted as a question, but it can also easily be
| interpreted as a shallow dismissal of their choice of Rust,
| which is a fairy common thing on HN. If you had laid out
| some details on why the choice puzzled you, your comment
| would probably have been interpreted more charitably.
| thwarted wrote:
| Performance is especially important when dealing with
| time syncing.
| tedunangst wrote:
| I think consistency is more important than actual
| execution time. Python will certainly have more latency
| responding to time queries, but it will be consistent and
| likely indistinguishable from a faster program.
| kelnos wrote:
| I didn't downvote your original post, but I just think
| these "why did they use language X instead of Y?" questions
| are kinda boring and tiresome, for the most part.
|
| If your goal is memory safety, Rust is a good choice. If
| you additionally want something mainstream (such that it's
| unlikely that you'll have trouble finding contributors or
| future maintainers), Rust is also a good choice, and
| Haskell and OCaml probably aren't. And who knows, perhaps
| the people building this were just familiar with Rust, but
| not Haskell or OCaml.
|
| But really, "It's unclear why X was chosen over Y or Z" is
| just not interesting. If the article doesn't say why, then
| we're just speculating. And in this particular case, I
| think the answer is probably pretty simple, obvious, and
| boring, anyway; I don't think it's "unclear" at all.
| lmm wrote:
| The idea that Rust is more mainstream than Haskell or
| OCaml sounds pretty crazy. I like the language but it's
| much younger and you don't see established companies
| using it the same way.
| tedunangst wrote:
| Rust inherits mainstreaminess by having an execution
| model similar to mainstream languages like c++.
| wmf wrote:
| Rust is mainstream in a way that OCaml or Haskell will never
| be.
___________________________________________________________________
(page generated 2022-10-11 23:00 UTC)