23 ms·
Deciding to rewrite getaddrinfo in rust
- Someone1234 11y agoIs there a good reason why a binary compatible glibc couldn't be re-written in a better language? People are always going to be using C/C++ and there is little that can be done about that exposure, but at least the libraries they rely upon could be better engineered to have certain assurances about safety.
- moron4hire 11y agoThere could be bad habits built into glibc that everyone has just learned to live with, that Rust explicitly forbids, or makes difficult to reimplement, such that doing so would reintroduce all of the same problems as before.
- acdha 11y agoI don't think there's a reason why it couldn't happen at least in parts – it sounds like that's Mozilla's plan for migrating parts of Gecko – but I suspect you'd hit an 80/20 rule pretty hard where many programs could use your alternate libc but a fair amount of code would have different results due to arcane details for things like threading, signal handling, etc. and it would be quite time-consuming to hit complete compatibility.
- agwa 11y agoI don't think it would be worthwhile to rewrite all of glibc, at least not initially. We should focus first on libraries that parse attacker-controlled input, such as glibc's DNS resolver, image libraries, font libraries, etc. Most of glibc does not parse attacker-controlled input and is probably already safe.
- lmm 11y agoYou'd lose most of the safety. E.g. a lot of the value of Rust comes from ownership tracking, but you can't track ownership across a C-ABI boundary because the information simply isn't there. And I'm not sure assurances in libraries used by unsafe languages are really that valuable - it'd be like locking your back door and leaving your front door open. Better to make a clean break.
- otabdeveloper 11y agoMost of the bad stuff in glibc is due to bad API's, not to bad programming languages. (E.g., non-reentrant functions with global state, functions that deliberately crash on incorrect input, poor separation between standard library functions and non-standard but commonly accepted ones, poor separation between stuff that's needed for C and stuff that wraps kernel/syscall functionality, etc.) Parts of it probably should be replaced with safer implementations, but as long as you're going for 100% compatibility you're still putting lipstick on a pig.
- pjmlp 11y agoMicrosoft re-wrote their C runtime library in C++, taking advantage of the language features for writing safer code. https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/ https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great...
- akerro 11y agoPlease call your implementation getaddrrinfo
- armitron 11y agoIt boggles the mind how utterly misguided the "let's rewrite everything in Rust!" people are when it comes to understanding security and its implications. Let me begin by introducing my premise: Rust will do NOTHING for security, it is not an improvement in any way, and at least as far as security is concerned, it will lead to at best colossal time waste, at worst actively damage the cause by misdirection, making ppl feel warm and fuzzy, providing illusion of security. What??? B-b-but memory safety, I hear you say. How can this even be possible I hear you cry. Memory safety (assuming that Rust completely solves it, which it absolutely DOES NOT) is but one (small) piece of the entire puzzle. In the same way that the skilled craftsman knows that he can't build a castle on top of sand, the skilled (and security conscious) software engineer should realize that memory corruption (and race conditions in the same unit/process) are not the foundation of the security chain. I dare say that a lot of the bugs exploited out there today (but not necessarily made public), are pure LOGIC bugs (that include race conditions) that stem from the interactions between extremely complex autonomous subsystems. Rust is simply operating at a too high-level abstraction layer to deal with any of these issues. This is the logical progression of Sergey Bratus's weird machines taken to the next level. Some examples: The Linux kernel. Any UNIX operating system taken as a whole. Any Windows taken as a whole. Any OSX system. Anything built on top any of the above. Anything built on combinations of any of the above. Weird machines are not limited to isolated units, you know, they very well exhibit EMERGENT behavior. Are you starting to get the picture now? And then of course we still have the bugs that stem from unsafe languages, as long as there's a path that cuts through all the intermediate layers of "safe" code. Graphics drivers and webgl anyone? Truetype in the kernel? Rust has plenty of things in its favor but to position it as a cure for issues that it doesn't even know how to address is a colossal mistake. We have given rise to a beast that threatens to consume us all. It's one thing to despair due to the immense complexity of the domain and quite another to step into an imaginary realm and solve illusionary problems that we create just to feel "safe".
- geofft 11y agoIt boggles the mind how people think the only benefit of Rust is memory safety. Rust has novel features for solving concurrency issues, what you call "pure LOGIC bugs (that include race conditions)". Of course memory safety is one small piece of the entire puzzle. That's why Rust has features besides just being a memory-safe version of C.
- lmb 11y agoThe comment about changing the const pointers is subtly wrong. There are pointers to const memory and there are const pointers to memory. My favourite little known C fact. See also http://stackoverflow.com/questions/1143262/ http://stackoverflow.com/questions/1143262/
- delroth 11y agoThat's not really "little known". Almost every single piece of code that does string manipulation in C uses that fact: const char* s = ...; while (*s++) { ... }
- aidenn0 11y agoconstant pointers are arguably little-known, though pointers to constants are well known.
- lmb 11y agoI think you have proven my point. I'm talking about this: void something(const char* const s); Maybe I'm extrapolating here, but it surprised me.
- dcohenp 11y agoThat is indeed what the post you're replying to meant. Note that the pointed-to value is a constant string, yet the pointer itself is being modified. That's a fairly common idiom in C string-handling code, only possible because it's a const char , not a const char const.
- asveikau 11y agoAgree with the other comments that this is most decidedly not "little known". The author loses all credibility in all C topics for saying this is poor form.
- lmb 11y agoNot sure who your issue is with, me or the author of the article?
- tinco 11y agoglibc in total is about 460.000 lines of C. If we're planning on reimplementing it as a whole that's going to be quite an undertaking. Musl is an alternative libc that's only about 60.000 lines of C. I don't know exactly why libc is that much larger, as musl also aims to be a complete and POSIX compatible libc. Its getaddrinfo is considerably smaller at 90 lines, and there's no goto's, it looks comfortably readable at a glance. Maybe a nice blog post would be to compare both implementations to find out if there's a concrete difference in functionality and code quality. edit: I should've looked at the 2nd Google result, it's a complete comparison of a bunch of libc's: http://www.etalabs.net/compare_libcs.html http://www.etalabs.net/compare_libcs.html
- michaelmior 11y agoI think Musl would probably be a better starting point for a libc rewrite. It would be cool if people were willing to take this on.
- pm215 11y agoSome of that will be glibc's coverage of a much wider range of architectures and host OSes than musl (a very back-of-the-envelope wc -l suggests that somewhere between 20 and 25% of glibc code is in sysdeps/ or ports/sysdeps/), but that's clearly not the only thing contributing to glibc being bigger.
- belorn 11y agoThere is also GNU specific functions and macros in glibc. Is musl implementing _GNU_SOURCE? I know that my own project use TEMP_FAILURE_RETRY macro quite heavily, among with asprintf.
- hawski 11y agoThis comparison is mentioned here or there, but it is important to add that it's not that recent. musl 1.1.5 was released on October 2014 glibc 2.19 was released on February 2014 Author of that page should probably add at the top of the page big header "2014". I can't find contact info to ask of him to do that though.
- agwa 11y agoHow security sensitive is getaddrinfo? The recent vulnerability was actually in glibc's DNS client library, libresolv, not getaddrinfo itself (but it was triggered when using getaddrinfo). Therefore, I think that rewriting libresolv in Rust (and possibly the DNS NSS module) would be more fruitful than trying to rewrite getaddrinfo. It would also be easier - libresolv is in its own .so so you could swap the entire thing out, rather than having to patch glibc or use LD_PRELOAD hacks. (I actually started working on this a few days ago :-)
- yyin 11y agoIs ldns vulnerable? Did OpenBSD drop BIND and libresolv in favor of ldns and nsd, unbound, drill? Might be an interim solution.
- Sanddancer 11y agoYes, OpenBSD dropped BIND, as did FreeBSD.
- codygman 11y agoReally hope you post this!
- JustSomeNobody 11y agoHow many new vulnerabilities and bugs will be introduced by doing this ya think? Rust in and of itself won't make things all better.
- Xcelerate 11y ago> fun aside, name and service are both const char* so I find it funny that they are set in the program, I do understand that from the callers perspective they don't change, but still bad form Correct me if I'm wrong (I haven't programmed in C++ in forever), but aren't "name" and "service" pointers to constant arrays of characters rather than constant pointers to (mutable) arrays of characters? In the first case, you're saying you have a variable that points to a memory location; the variable itself can be changed, but the data in memory at that location cannot. In the second case, you're saying that you cannot change the variable that contains the memory address; however, you can change the data in memory at that location. (And if I remember correctly, I believe there are also such things as constant pointers to constant memory...)
- mbrock 11y agohttp://cdecl.org/ http://cdecl.org/ const char *foo declares a pointer to a char that is constant. const char * const foo declares a constant pointer to a char that is constant.
- teddyh 11y agoYou know, you could just apt-get install cdecl And then do it on the command line. But hey, let's turn everything into a web service, with NSA et al. monitoring as a bonus feature.
- deleted 11y ago[deleted]
- MichaelBurge 11y agoI know that it's used for more than just C programs, but it still seems a little perverse to rewrite the C standard library in something other than C. Imagine if someone had a preference for writing his Python libraries in Perl that emitted Python bytecode. Or if C++'s Boost was the output of a Haskell program.
- dalailambda 11y agoOn the other hand, how many languages use libraries that are written in C? Especially in the higher level scripting language ecosystems(JS, Python, Lua) a lot of libraries interface with C/C++ libraries. If instead they used Rust, would that not result in a gain for those languages(even if there was a small C wrapper around it)?
- Santosh83 11y agoI get what you mean, but I guess calling it the "C Standard Library" is really a historical holdover from times when the entire system was written only in C (with the exception of a smattering of assembly). In the current context it should probably be called the "System Standard Library" and when you consider it like that, a system standard library in another language isn't all that weird. They all compile down to machine code anyway, so the Python-Perl analogy doesn't quite match.
- pjmlp 11y agoUNIX is the C runtime, kid of. They just didn't want to force it into other OSes when ANSI C was defined and eventually POSIX took up that role.
- _yosefk 11y agoActually many people have a preference for writing their Python libraries in C :-) Python was explicitly designed under the assumption that much of the heavy lifting will happen in C. And C programmers write their parsers in Yacc, etc. (This is not to say that rewriting libc is a good way for people knowing Rust to spend their time. It's a ton of effort with the result most likely to be unused and if it is used, then it provides a small benefit to C and C++ programs at the expense of a rather scarce resource - Rust developers - having been diverted from benefiting Rust programs. If I were a Rust enthusiast, I'd much rather write libraries in Rust designed to be used in Rust programs so that more such programs get written more quickly than use Rust to put lipstick on the pigs that are C and C++.)
- saghul 11y agoAnother potential source of inspiration is Musl: http://git.musl-libc.org/cgit/musl/tree/src/network/getaddrinfo.c http://git.musl-libc.org/cgit/musl/tree/src/network/getaddri...
- w8rbt 11y agoSome people, when confronted with a problem, think “I know, I'll rewrite this in another programming language.” Now they have two problems.
- maxerickson 11y agoThis is a great story to make glib comments on.
- w8rbt 11y agoThis glib comment has a long history in technology. So it seems appropriate. http://regex.info/blog/2006-09-15/247
- steveklabnik 11y agoI thought your parent was making a pun about 'glibc' and 'glib'.
- chillingeffect 11y agoSo many tentative posts here :) I say, "Go for it!" Kozlowski's attitude is exactly what we need. That's not saying it will ship in Ubuntu 18.04... It will be carefully vetted just like any piece of software, but it's got to start somewhere and I like that he's sharing his thought process with the community. As people have pointed out, it may not actually be the Rust part of it that's valuable, but the organization and code quality. Rah rah!
- oconnor663 11y agoI'm not so sure about the attitude. > After reading about the newest glibc vulnerability, I have decided to see how much effort there is in rewriting parts of glibc in a safe language. If I were a C programmer, especially if I were a C programmer who worked on glibc, I might feel a little bit insulted that remark. Safety is a complicated concept, and calling Rust "safe" and C "unsafe" oversimplifies things, especially if your Rust code includes unsafe blocks. See also http://www.tedunangst.com/flak/post/heartbleed-in-rust http://www.tedunangst.com/flak/post/heartbleed-in-rust. I don't think we have anything to lose by being as diplomatic as possible with these sorts of things. We can acknowledge that Rust's safety is a work in progress, and that we're still learning about the drawbacks.
- betenoire 11y agoit might oversimplify it, but there is truth in there too
- agentgt 11y agoHas anyone successful linked to a Rust library from another language (ie Python). I know Rust offers FFI and will apparently make its data representations C like if annotated and I think has some ABI. This is the second post I have seen in the last couple of days of "glibc is bad lets rewrite it in Rust". However the problem is not that glibc is just bad but rather everything links to it. If other languages can't talk to Rust easy this would be a nicer problem to focus on first (before rewriting glibc). I guess this is sort of how its done: http://siciarz.net/24-days-of-rust-calling-rust-from-other-languages/ http://siciarz.net/24-days-of-rust-calling-rust-from-other-l... Rust -> C <- Other language. You have to create the C header files (I'm surprised Rust compiler or something similar doesn't automate this).
- dikaiosune 11y agoI don't know when this was last updated, but: http://jakegoulding.com/rust-ffi-omnibus/ http://jakegoulding.com/rust-ffi-omnibus/ It's got a nice breakdown of how to bring rust libraries into a few languages. There are a few tutorials about how to make rust produce a static or shared library, but it's pretty straightforward.
- kobyszcze 11y agoI wrote a simple example of calling out into Rust from Python using cffi: https://github.com/maciejkula/python-rustlearn https://github.com/maciejkula/python-rustlearn. The gist of it is: it's really easy.
- Dobbs 11y agoSkylight[1] from what I understand is a ruby gem written in Rust. It monitors your ruby runtime and sends the data to the central servers for analysis. 1: https://www.skylight.io/ https://www.skylight.io/
- steveklabnik 11y agoIt was also one of the first production uses of Rust.
- dikaiosune 11y ago
- mikegerwitz 11y agoI understand why people want to rewrite C libraries and such in Rust. Software like glibc is battle-tested---it is _widely_ used on hundreds of thousands of systems around the world, and has been used (though not at today's massive scale) for decades. I understand that glibc is under active development and there is a lot of new code, but let's keep this in perspective: Writing a new implementation of a system is a huge opportunity to introduce bugs. There is focus on these specific problems, but in the broader scheme of things, glibc is remarkably stable, performant, and feature-rich. A new implementation will have bugs, and those bugs might be less likely to be caught simply because the system will not be as widely used for quite a long time. Even formally proven systems don't address flaws in the actual program specification. (See "The Limits of Correctness" by Brian Cantwell Smith for a good discussion). Also relevant (which I'm reminded of in part because of his recent death): Peter Naur's Programming as Theory Building. So even _new_ code to glibc has the benefit of a huge community of both developers are users to eyeball it and test it out in production on a huge number of systems. So rewriting glibc may solve certain problems, but it's bound to create a whole lot more, considering the narrow range of issues that are being focused on. New Rust code will have undiscovered issues too, even if they're not memory or stack related. I feel that this effort might be better spent fixing and finding problems with glibc---and continuing the development of tools to find those problems, to benefit _all_ of our old C libraries and programs---than rewriting for the sake of rewriting.
- pcwalton 11y ago> New Rust code will have undiscovered issues too, even if they're not memory or stack related. Memory issues have a tendency to be the most severe types of issues from a security perspective. (Not always, but with a high frequency.) Other issues that may occur with a rewrite may be security problems as well, but the security track records of network-facing software written in old-timey C speak for themselves: memory safety issues make up a huge fraction of their vulnerabilities. > I feel that this effort might be better spent fixing and finding problems with glibc---and continuing the development of tools to find those problems, to benefit _all_ of our old C libraries and programs---than rewriting for the sake of rewriting. So we've been trying that for the past 35 years since C was released in 1978, and we've completely failed to move beyond making the same basic memory management errors again and again and again. I think that if we couldn't do it in 35 years, we aren't likely to be able to by just trying a little harder this one time.
- minitech 11y agoMinimalism comes in many forms. Here, we see an example of a content-free article. > fun aside, name and service are both const char* so I find it funny that they are set in the program, I do understand that from the callers perspective they don't change, but still bad form … are you sure you know enough C to do this?
- deleted 11y ago[deleted]
- armitron 11y agoNot only that, but most people in this thread are STILL missing the multiple elephants in the room. First, Rust allows unsafe code in the core language [not simply through FFI as in other safe languages]. So there's a gaping hole that we know will be abused (performance! performance!) right there. Even if we grant that this is not the case, here is the deal breaker: The Rust approach to security depends on an ecosystem that follows the same approach. To think that this is more than an utopic dream is to enter cuckoo-land in my opinion. So we digress back to the castles-built-on-top-of-sand. There's millions of lines of code written in unsafe languages plus all mainstream operating systems. The Rust approach will never work in this sort of environment. An approach that might work however is unikernels and using a language that promotes design with failures in mind [and makes it extremely easy to rapidly rearchitect/rebuild/redeploy]. Erlang is the best example in my view, but there could be more. Alas, Rust is not really suitable for this either due to its static nature.
- dang 11y agoYour comments in this thread have been inflammatory, condescending, and vague. That amounts to trolling, whether you intended to or not. You've done it quite a bit in previous threads, too, which is not good. Please don't do this on HN. Here is how to stop: (1) take out everything inflammatory ("It boggles the mind how utterly misguided", etc.) and make neutral statements instead; (2) take out the personal language ("you just don't get it", etc.); (3) replace vague grand claims with specific factual statements. If you do this, you'll not only no longer be breaking the HN guidelines, you'll also be sharing what you know more effectively, which benefits all of us. We detached this subthread from https://news.ycombinator.com/item?id=11162577 https://news.ycombinator.com/item?id=11162577 and marked it off-topic.
- deleted 11y ago[deleted]
- steveklabnik 11y ago> we know will be abused (performance! performance!) None of the programs (or at least most, I only checked the first 5) in which Rust is faster than C use unsafe directly. It's in the libraries they use, but safe Rust is very performant. We'll have to agree to disagree about the rest. :)