← Back to context

Comment by AYBABTME

8 years ago

This comes around to me as something that just shouldn't have happened. CloudFlare are pretty big on Go, as far as I can tell (and I guess Lua for scripting nginx). Why was this parsing package written in a non memory-safe language? Parsing is one of those "obvious" things easy to mess up; the likelihood of a custom, hand written parser being buggy is pretty high. If it's somehow understood that your library is likely to have bugs, why do it in C/C++, where bugs often lead to bleeding memory? In a shop that's already fluent in Go, where they have the institutional knowledge to do it safely? Sure performance is not going to be the same, but with some care it'll get pretty close.

Sorry I hate to just be a coach commentator. Obviously hindsight is 20/20. Still I think there's a lesson here.

True. I don't understand why many of us programmers are not interested in tools that eliminate the possibility of errors?

* Why do we use memoy-unsafe languages (except when Rust or GC is unusable)? * Why do we use type-unsafe languages, at all? * Why do we use state-unsafe (mutable) languages, at all?

Of course there are exceptions to these - but they are few.

  • There aren't so many languages that are a) memory safe, b) type safe, and c) thread safe, that additionally offer d) a large enough pool of developers to recruit from.

    • You don't need (d) but lest anyone realise it. Now get me a Java dev whose been sitting in a chair at a desk for 10k hours.

The blog post makes it seem like the problem was in an nginx module. Looking at the docs [1] it looks like that's a C API; as far as I know writing shared libraries in golang for a C caller isn't really a thing (because the runtime needs to exist). Rust might have better luck here (I _think_ there have been attempts to get rust code loaded by not-rust code), but I haven't kept track.

[1] https://www.nginx.com/resources/wiki/extending/api/main/

This could easily happen in Go as well. All that would be needed is to reuse the buffer in between requests, and rely on the buffer length instead of clearing it.

To make it safer you would need to deallocate and reallocate the buffer for each request, but that might be slow. Doing that would fix it for Go, or for C, it would be the same either way.

So I'm not convinced that using Go would have helped here.

  • It's a good point, but at least with Go the leak would be limited to the allocated buffer. This is probably a case where Rust or C++ might be more helpful. Presumably you wouldn't want to allocate a new (variable sized) buffer each time (particularly in a GC language), but you could create a new (bounds checked) slice[1] / array_view[2] / gsl::span / RandomAccessSection[3] each time.

    [1] https://doc.rust-lang.org/nightly/std/slice/

    [2] https://github.com/rhysd/array_view

    [3] https://github.com/duneroadrunner/SaferCPlusPlus#txscoperand...

  • I agree. I keep seeing comments about C being the culprit, but in my mind, this is more of a policy issue regarding how any given language initializes and allocates memory.

    Sure, in this case, we may see a C-specific bug in play, but I think this sort of bug is more effectively mitigated by forcing buffers to be zero-filled upon allocation and/or deallocation, and perhaps system-wide at the OS level, rather than relying upon language features to cover it.

    So - I'm not explicitly defending C here - I just don't think a similar bug could never occur in a "memory safe" language as well.

  • That is true, but reusing buffers in Go is a lot more deliberate an action than in C. The possibility is still there, but I think it's way harder to mess up.

It is not the fault of the language if you use it wrong.

CloudFlare is to blame here, nothing else.

As for the reason why C, I'm pretty confident they knew what they were doing, and had considered other tools that did not meet all requirements.

  • Allow me an analogy. It's not the fault of a rope if you use it to cross between two skyscrapers and slip and fall to the ground. But if if you mind your life you use at least a safety cable to tie you to the rope, or use the lifts and cross at road level. There are still cars to watch for, but...

    C is simply too dangerous, even the best developer can slip without noticing. There are safer alternatives now, we should start using them at least for new projects.

  • Security is a requirement. They must have been extremely confident indeed to write something like this in C, where a single mistake can make your program fail in catastrophic ways, with no help whatsoever from the compiler.

    If some code has bugs, did the author just "use the language wrong"? People make mistakes, and we can prevent some of them by using better tools.

  • No, the language is bad if using it wrong can leak sensitive data.

    The choice of language is wrong if you pick such a language in a situation where mistakes can lead to safety or security problems.

    The first requirement is security.

    • But - I can't think of a single language in which using it "wrong" might not lead to info leaks? Any language with a runtime has to manage memory somehow at the runtime layer and so similar leaks can occur there depending upon design and implementation, and the wider OS context.

      At the whole program/application level, when you create your own data structures, you can find lots of ways to leak them to the world.

      2 replies →

    • You can leak sensitive data with any language. C is not used for web development on the client side, yet people abuse security holes in web apps all the time.

      1 reply →

Memory safe languages aren't a panacea. There could just as easily have been a bug in the compiler or standard library with the same result.