Live data from Hacker News

More Memory Safety for Let's Encrypt: Deploying ntpd-rs

letsencrypt.org

21–30 of 177 posts

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#21
post #19
post #9

Earlier quoted context omitted.

This is a good question to ask, especially in the age of everything pulling in every possible dependency just to get one library function or an `isNumeric()` convenience function. The answer is that there is observability functionality which provides its results as JSON output via a UNIX socket[0]. As far as I can see, there's no other JSON functionality anywhere else in the code, so this is just to allow for easily…

If the pieces of state are all well known at build time - and trusted in terms of their content - it may be feasible to print out JSON 'manually' as it were, instead of needing to use a JSON library, print "{" print "\"some_state\": \""; print GlobalState.Something.to_text(); print "\", "; print "\"count_of_frobs\": "; print GlobalState.FrobsCounter; print "}"; Whether it's worth doing this just to rid yourself of a…

Even better to just use TSV. Hand-rolling XML or JSON is always a smell to me, even if it's visibly safe.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#22
post #15

Why does your ntpd have a json dependency?

Would you rather it had a JSON dependency to parse a config file, or yet another poorly thought out, ad-hoc homegrown config file format?

> yet another poorly thought out, ad-hoc homegrown config file format

OpenBSD style ntpd.conf:

    servers 0.gentoo.pool.ntp.org
    servers 1.gentoo.pool.ntp.org
    servers 2.gentoo.pool.ntp.org
    servers 3.gentoo.pool.ntp.org

    constraints from "https://www.google.com"

    listen on *
I mean, there's always the possibility that they used a common, well known and pretty decent config file format. In this particular case, this shouldn't be the thing that differentiates your ntpd implementation anyways.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#23
post #15

Why does your ntpd have a json dependency?

Would you rather it had a JSON dependency to parse a config file, or yet another poorly thought out, ad-hoc homegrown config file format?

Poorly thought out, ad-hoc homegrown config file format, please. Every time.

1. Code doesn't change at the whims of others.

2. The entire parser for an INI-style config can be in about 20 lines of C

3. Attacker doesn't also get to exploit code you've never read in the third party dependency (and its dependencies! The JSON dependency now wants to pull in the ICU library... I guess you're linking to that, too)

4. Complexity of config file formats are usually format-independent, the feature-set of the format itself only adds complexity, rather than takes it away. To put it another way, is this any saner...

    {"user":"ams","host":"ALL","runas":["/bin/ls","/bin/df -h /","/bin/date \"\"","/usr/bin/","sudoedit /etc/hosts","OTHER_COMMANDS"}
... than ...

    # I may be crazy mad but at least I can have comments!
    ams ALL=/bin/ls, /bin/df -h /, /bin/date "", /usr/bin/, sudoedit /etc/hosts, OTHER_COMMANDS

All the magic in the example is in what those values are and what they imply, the format doesn't improve if you naively transpose it to JSON.

An example of an NTP server's config:

    # I can have comments too
    [Time]
    NTP=ntp.ubuntu.com
    RootDistanceMaxSec=5
    PollIntervalMinSec=32
    PollIntervalMaxSec=2048

If you just want key-value pairs of strings/ints, nothing more complex is needed. Using JSON is overdoing it.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#24
post #19
post #9

Earlier quoted context omitted.

This is a good question to ask, especially in the age of everything pulling in every possible dependency just to get one library function or an `isNumeric()` convenience function. The answer is that there is observability functionality which provides its results as JSON output via a UNIX socket[0]. As far as I can see, there's no other JSON functionality anywhere else in the code, so this is just to allow for easily…

If the pieces of state are all well known at build time - and trusted in terms of their content - it may be feasible to print out JSON 'manually' as it were, instead of needing to use a JSON library, print "{" print "\"some_state\": \""; print GlobalState.Something.to_text(); print "\", "; print "\"count_of_frobs\": "; print GlobalState.FrobsCounter; print "}"; Whether it's worth doing this just to rid yourself of a…

> If the pieces of state are all well known at build time - and trusted in terms of their content

.. than use library, because you should not rely on the assumption that next developer adding one more piece to this code will magically remember to validate it with json spec.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#25

Unlike say, coreutils, ntp is something very far from being a solved problem and the memory safety of the solution is unfortunately going to play second fiddle to its efficacy. For example, we only use chrony because it’s so much better than whatever came with your system (especially on virtual machines). ntpd-rs would have to come at least within spitting distance of chrony’s time keeping abilities to even be up for…

The biggest danger in NTP isn't memory safety (though good on this project for tackling it), it's

(a) the inherent risks in implementing a protocol based on trivially spoofable UDP that can be used to do amplification and reflection

and

(b) emergent resonant behavior from your implementation that will inadvertently DDOS critical infrastructure when all 100m installed copies of your daemon decide to send a packet to NIST in the same microsecond.

I'm happy to see more ntpd implementations but always a little worried.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#26
post #19
post #9

Earlier quoted context omitted.

This is a good question to ask, especially in the age of everything pulling in every possible dependency just to get one library function or an `isNumeric()` convenience function. The answer is that there is observability functionality which provides its results as JSON output via a UNIX socket[0]. As far as I can see, there's no other JSON functionality anywhere else in the code, so this is just to allow for easily…

If the pieces of state are all well known at build time - and trusted in terms of their content - it may be feasible to print out JSON 'manually' as it were, instead of needing to use a JSON library, print "{" print "\"some_state\": \""; print GlobalState.Something.to_text(); print "\", "; print "\"count_of_frobs\": "; print GlobalState.FrobsCounter; print "}"; Whether it's worth doing this just to rid yourself of a…

That’s somewhat better than assembling, say, HTML or SQL out of text fragments, but it’s still not fantastic. A JSON output DSL would be better still—it wouldn’t have to be particularly complicated. (Shame those usually only come paired with parsers, libxo excepted.)

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#28
This seems like a weird place to be touting memory safety.

It's ntpd, it doesn't seem like a place for any sort of attack vector and it's been running on many VMs without exploding memory for a while now.

I'd think there are far more critical components to rewrite in a memory safe language than the clock synchronizer.

Re: More Memory Safety for Let's Encrypt: Deploying ntpd-rs

#30

This seems like a weird place to be touting memory safety. It's ntpd, it doesn't seem like a place for any sort of attack vector and it's been running on many VMs without exploding memory for a while now. I'd think there are far more critical components to rewrite in a memory safe language than the clock synchronizer.

It's present on loads of systems, it's a very common service to offer, it's a reasonably well-constrained use case, and the fact that nobody thinks about it might be a good reason to think about it. They can't boil the ocean but one service at a time is a reasonable approach.

I'll flip the question around, why not start at ntpd?

Post reply on HN