Rewrite Everything in Rust
robert.ocallahan.org
robert.ocallahan.org
Rewriting the software in Rust would not solve these problems any more than rewriting it in C++ would. A rewrite would clean up the code, sure, but then you're left in the same situation, only with brand new bugs that nobody has time to fix.
We need to have incentives for maintaining this foundational software.
The entire point is that you're not in the same situation regarding memory safety problems/vulnerabilities.
I imagine the top two reasons unsafe memory access happen is:
1) other complicated logic seeped into the memory sensitive area or causes programmer fatigue
2) memory management is hard
Rust helps with #2 but let's not kid ourselves, what percentage of a library like glibc would be spent in unsafe blocks? Drawing attention to an unsafe area can help though.
As you can see, I'm running around in circles. Just like every discussion about this does. Until an avid Rust user puts their money where their mouth is, we're all just playing Armchair Programmer.
> Rust helps with #2 but let's not kid ourselves, what percentage of a library like glibc would be spent in unsafe blocks?
string.h is not as interesting as, say, the DNS resolver. Nothing about the DNS resolver needs to be unsafe.
I think the hesitation there is that everyone has gotten it beaten into your head that writing new crypto libraries is dangerous. It's probably safer to use a library that has tons of eyes on it, but at some point we should do it.
But maybe for openssl staying close to the original API is useful, then one could maybe put a C API on top and use it also outside Rust.
But in general, I think that entire idea is that as more code moves to memory-safe languages, the less need we have for unsafe sections.
Ideally, once the kernel itself can be written in a memory safe language, everything running on top of that wouldn't need much unsafe blocks. To be honest, this goal is probably decades away, but we should definitely be considering memory-safe languages for systems programming.
Probably less than you think. What I think the limit is is that there are functions in glibc that present inherently unsafe interfaces. I'm not sure how many but it might be enough that writing libc in Rust is not that helpful.
There are lots of people doing this. Look at crates.io. I decided to write a new fully compliant DNS server and client, trust-dns. I work on it in my spare time (it's time not money), which is hard with two kids.
I've learned a few things. It's hard to get it done. There's a lot to learn from the rfc's. Just because it's Rust, doesn't mean it's easy. There are all the same borrow rules, and I know I have a bunch of TODOs in the code to go fix things like extra clones. The IDEs, while good, are not on par with other languages yet.
Basically it's a lot of work. And I commend the individuals who've paved the way for me with the std library in Rust, but we still have so much more work to do until there is a full OS env like GNU.
In all safe alternatives to C, just like Rust sure you need unsafe at the Assembly FFI level and hardware integration like IO ports and interrupt handling.
But everything else can be just plain safe code.
(Incidentally, there are other classes of vulnerabilities that Rust and/or its libraries heavily mitigate, such as deserialization issues along the lines of the Rails YAML bug.)
> Part of what makes Rust awesome is it forces correct...architecture.
If you believe that, and follow it, then you will end up with a lousy architecture. A correct architecture cannot be designed without knowledge of the problem domain.That's the problem with security too: if you believe the language will keep you safe, and stop thinking about security, your software will be less secure than before. There's plenty of insecure Java code out there.
> if you believe the language will keep you safe
safer != safe.
And if you use "it won't be perfectly secure under X mitigation strategy" as an excuse to avoid doing X, your software will also be less secure.
With all of that said however, I agree with you that it would be foolish to think that a rewrite would not be open to lots of potential vulnerabilities. At the moment might be prudent to continue to use and support the current libraries, but to also support efforts like rust-crypto in order to prepare for the future.
None of these things (except maybe some of the concurrency stuff) are quite new to Rust. It's just that C is such an old language that stuff that other languages have been doing well for decades were not available to systems software.
I think an interesting question is, why are there so many contributors to the Linux Kernel in comparison to something like glibc? Both, I'd argue, are equally foundational.
I used to do systems programming back when the only OS written in C was UNIX.
C wasn't the first systems programming language.
Burroughs B5500 was written in Algol 68 with zero lines of Assembly. Just one example from many others in the pioneering days of computing.
There are other approaches to writing OSes.
If UNIX community ever wants to divorce from C there is a way, but there needs to exist a will as well.
N.B.: I have never and will never ask for, nor accept any income from OSS work: too much shit-flinging and absurd expectations. But as a _user_ I want OSS, for its own sake, to re-evaluate its attitude towards money.
I.e., if you start paying; you have to continue paying.
Predictably Irrational http://whistlinginthewind.org/2013/01/15/predictably-irratio...
You don't want to pay anymore, go back to glibc...
But Google does run a security-engineering focussed bounty program: https://www.google.com/about/appsecurity/patch-rewards/
So if you're looking for some smaller scale rewards, that might help.
It's absolute nonsense - so many of the most successful free/open source software projects are those with salaried employees working on it, and this has been the case for many years. The problem today is of course finding a way to fund open source contributors whose projects aren't quite aligned with the needs of a major company.
How about something like https://gratipay.com/
So I don't think that saying there will be bugs in the new libraries, too, is fair criticism.
Also, what's clear is that Linus Torvalds' "just don't be stupid and write incorrect code" policy doesn't work. We need to think of security from a design point of view, not rely on your average programmer to write academically perfect code as a security policy.
Rewriting in Rust, increases the contributor pool for these project from some x to some y. Where x is the subset of people in [1, 2, 3, 4, 5] and y is the subset of people in [1, 4]:
1. Who are eager and have time to help
2. Who know manual memory management really well (also diligent enough to use that knowledge appropriately) [Made redundant by compiler]
3. Who can successfully build, link and test C code on multiple platforms [Made trivial by Cargo]
4. Have appropriate domain knowledge
5. Are not afraid to refactor "working code". [Made better through first class testing, the compiler and community mindset]
There is also the aspect that experts get a dramatic boost to their productivity, reducing their time needed, and therefore reducing the level of incentives needed.
The compiler doesn't obviate the need to understand memory management. Anyone who doesn't understand ownership and borrowing will have really hard time getting rustc to accept their code in the first place.
What Rust's type checker does is make up for the human inability to be perfectly careful. Even the most diligent programmer will make mistakes or forget something. (This is a fact of life. It can't be fixed with present-day technology.) Relative to C and C++, Rust enlarges the class of “stupid mistakes” that can be detected automatically, and this is always a good thing, no matter how knowledgeable and careful programmers are.
Couldn't agree more. Incidentally, this is also what I dislike so much about C: it does a very poor job of telling the programmer what is wrong with their program. Learning systems programming with C feels (to me, at least) like learning to walk by crawling in the dark.
Originally I thought it was just joe-randoms-query lib I used in project at work.
But the last year I had time to look at more desktop bound programming and see that it really is the whole stack.
It's my opinion that contributing to free software is a public good, and so we should have state-funded employees whose full-time job is to work on this software. I think something like this is already done in places like France and Europe, but to my knowledge the majority of paid-for American contributions to FLOSS comes from corporations.
BountySource?[0] I'm not affiliated with them, but they seem to fit that kind of spot from what I've seen so far.
Writing security critical software in c++/c is not the sensible thing to do in my opinion (even though it is the standard right now). Humans in general cannot handle it without making a lot critical errors. And the people working on those projects are already really smart in general. This has been shown again and again.
If c++ was a car, it would force you to place your foot in a special position in between breaking and accelerating. If you do it wrong, your foot will get squashed in the exposed drive train.
Of course for the point of the argument I am exaggerating, but I really applaud the efforts Rust has made in order to advance the security of software.
It's pretty much unheard of, but nearly every open source project would benefit far more from a week of watching potential contributors trying to get up to speed than it would from making sure the project roadmap is delivered a week sooner.
That's my claim for projects in general, and what you're asking for re Rust is a little different, but the approach can applied there, too. Focus on everything from navigating the project website and other docs, to interactions with the tools that make up the "ecosystem", to programmer expectations that could shape the language (with the latter actually being the least important).
Don't trust users to self-report. Don't overestimate your ability to make a combined diagnosis and prescription, and don't underestimate how much silent resignation is killing your adoption rate. Observe and work off real notes.
First, design a sound language that solves problems other languages don't (done). Then, optimize for adoption ... because the world only benefits from that new language once adoption really takes off.
Rust has done half the job really well. And a decent start on the second half -- mainly because the first half was done so well.
But if the Rust team were to prioritze adoption the way the parent post espouses, they'd be changing their priorities significantly, and it's probably the most effective way to make sure Rust fulfills its potential.
We have done some almost-studies like this: we had a series of conference calls with companies using production Rust specifically to work on their pain points, for example.
It would have been fantastic, if Rust took only a few steps further from Cyclone. I also wish that Rust authors stop adding more and more features. The target audience, namely low level system programmers, tend to work close to hardware and think along those lines, so bombarding them with type theory concepts is only going to shoo them away.
Just my 2 cents.
> I also wish that Rust authors stop adding more and more
> features.
I'm not sure what this is referring to. Rust hasn't added any features since the stable 1.0 release last May, and I also don't believe it added any features in the six-month beta period prior to that. And it's not an especially feature-heavy language in the first place, likely comparable in size to Python (e.g. a medium-sized language).The big ones though are:
* Specialization. This will allow you to write ultra-performent generic code by special-casing when you have the knowledge. It also will be a building block for the next few features.
* The bag of features colloquially known as "inheritance", though that's not really a good name.
* Non-lexical borrowing, and various other borrowck usability improvements.
* Abstract return types, which will allow for you to remove some allocation and make certain type signatures much better.
* Incremental compilation.
Those are the ones on the short list. There are others too, like higher kinded types.
Also features like that makes me wonder if you folks are really targeting C/System programmers. Sorry if I sound negative, that isn't my intention.
As a practical example of higher kinded types, you can't say "this function takes an Rc<T> or an Arc<T>. I just want something refcounted, but I don't care about how." HKT would get you there.
Another common problem it would solve is "I don't want to write both a &T and &mut T version of my function."
A good example is Phil's OS. http://os.phil-opp.com/. He's designing an operating system in Rust, and it has surprisingly few "unsafe" parts. The rest of it is made safe using some neat zero-cost abstractions.
Higher kinded types isn't going to happen anytime soon. It's something that crops up often in discussions when people want to model something complicated with the type system; but it's a very nontrivial feature that would probably need to wait for Rust 2.0, if ever. Even if it would exist, you can just not use it. Like most of the other features being added.
I didn't say that system programming does not need a good type system. I am also not saying that it is impossible to design operating system software with Rust.
As someone who had been on both the sides of the abstraction and having closely interacted with the system programmers, I think it is just too hard to convince them to use Rust. It is not just about the language alone, it is about what minimum you need to bootstrap a system (among many other things).
Anyway.. good luck to the OP in "rewriting everything in rust" and also getting it to the same quality/feature parity as others in the game and also get others to use it as well.
Yeah, I'm just saying that "higher kinded types" (which, again, Rust isn't getting anytime soon), does not make Rust something that isn't targeting systems programming; in response to "you folks are really targeting C/System programmers".
Many of Rust's designers are experienced systems programmers. A _lot_ of effort goes into making it systems-ready.
> it is about what minimum you need to bootstrap a system
Rust works on any target LLVM compiles to, and you can opt out of the standard library if you're writing baremetal things. There already are people writing low level Rust things.
But yeah, I know the skepticism you refer to; seen it in action before. But in the case of Rust I've rarely seen any concrete points being brought out (aside from perhaps "LLVM doesn't target enough things", which is fair). The language developers do try to take input from everyone and make it more systems ready; but there really isn't much that can be done when there isn't any input other than a strong preference for C.
That is promising. Thanks. I am certainly playing with it at home.
I counted about two people in the entire thread that have actually written code to support this much desired rewrite. The rest are chitchatting.
(One of the reasons it's this way is largely historic: so much was changing in the lead-up to 1.0 that I couldn't add many examples, as things kept changing out from under me.)
edit: This one? https://github.com/rust-lang/book.git
http://blog.dkhenry.com/2016/02/17/deciding-to-rewrite-getad...
I think the way to tackle a rust glibc rewrite:
Step 0 - write a code generator that just generates rust code that call the C versions of glibc symbols ( based off of the publicly exposed API in the library files). Get test suite to run
Step 1 - Make that rust code generate a 100% drop-in replacement fro the C symbols (maybe this requires injecting version numbers)
Step 2 - write the `getaddrinfo` replacement in Rust
???
Step 4 - have all of glibc ported
EDIT: Does anyone know of any gotchas with linking that would cause this to happen? Seriously considering taking a day off to do step O.
For step 1, you'd need to carefully look at glibc's ABI, which is even more complicated than its API due to backward compatibility and symbol versioning.
I get it, the idea is to replace this core low-level library with something you could maybe run C programs on top of. But damn, that is a crappy interface (which is specified by both an ISO standard and an IETF RFC so I must be an idiot, right?).
See Herb Sutter's talk at CppCon: http://herbsutter.com/2015/09/27/my-talk-at-cppcon/
For most applications, moving to modern C++ is going to be a better option than rewriting in Rust.
I will be happy if Rust's main impact on history will have been to showcase how to get those safety features into a practical language, and by extension improvements to C++, but I still think that the steps C++ is taking seem a lot less safe than what Rust has achieved by completely ignoring backward compatibility with C++98. See, for example, the compiler-enforced concurrency safety that Rust provides. I haven't read the core guidelines recently or in depth, but IIRC that's not a stated goal of the project.
You would have to break compatibility with too much existing code to get the same level of strictness as Rust, so that's reasonable, but yeah, it's hard to imagine that C++ will be as safe as Rust. I'm glad these features are being pushed through though.
Doesn't even have to do with concurrency. This leads to iterator invalidation and many other problems in single threaded code. In fact, Rust's "standard" concurrency guarantee (with regular, non-scoped threads) doesn't deal with the mutable aliasing rule; it works with the ownership rule more or less exclusively. Even if mutable aliasing was allowed in Rust, you could still build the same safe threading system assuming that borrows are still scoped[1].
The mutable-alias guarantee is more of a "don't let the rug be pulled out from under me". While this is something that's more obviously a problem in threaded situations where a mutation from a different thread can pull the rug out from under you, a function call in complex code that mutably aliases can cause the same issue. The classic example of this is iterator invalidation; but it works with any type which contains a variable amount/type of things, and severe logical (non-memory-safety) issues can be caused with anything with invariants.
See: http://manishearth.github.io/blog/2015/05/17/the-problem-wit...
[1]: When I say "safe", I'm assuming that in this situation (the lack of rules against) mutable aliasing itself isn't causing any unsafety elsewhere that transitively leaks down and causes thread safety to go kablooey. As such it's a necessary and mostly sufficient system of rules; removing one rule will probably make the whole house tumble. However, the point was that Rust's thread safety doesn't directly derive from the mutable aliasing rule.
I wouldn't bet on that.
Companies which go with a language like C++ don't do it for "safety" or "performance" or reasons like that (at least, most of the time they don't). They go with it because they can get something written once, then run it for the next half-century and only have to spend engineering time on new features and the occasional critical bug. Telling them they need an intrusive rewrite of their entire codebase to use modern practices will simply result in either (A) no action taken (most likely) or (B) the rewrite happening in a language that isn't C++.
This is incidentally what happened with quite a few significant Python codebases in the 2/3 transition -- rather than rewrite their code to Python 3 standards, they said "eh, we're rewriting anyway, let's go to Lua" (most often, though some other languages were the "let's go to" option as well).
Some people on this website seem to blow the python 2/3 transition fairly out of proporotions.. Python 3 is really extremely similar to Python 2, and there are great tools to convert Python 2 code to Python 3 and vice versa.
I've tried Pasteurize (part of python-future) but it just leaves the "yield from" statements in place, giving syntax errors. And 3to2 does even less, and seems to mostly be a framework for building tools like Pasteurize.
I know this isn't easy, but JavaScript people do it with ES6 transpilers, and ES6 is more different from ES5 than Python 3 is from Python 2.
In case you want to see the scripts I use to change the python3 code to python 2 and make it work with pip:
https://github.com/JelteF/PyLaTeX/blob/master/convert_to_py2...
Is it exception safe? Are my iterators always valid? Is this undefined behaviour?
So better keep a copy of the C++ standard open and keep reading whenever you feel unsure.
See also these posts:
* http://smallcultfollowing.com/babysteps/blog/2015/05/05/wher...
* http://smallcultfollowing.com/babysteps/blog/2015/05/29/clas...
* http://smallcultfollowing.com/babysteps/blog/2015/08/20/virt...
* http://smallcultfollowing.com/babysteps/blog/2015/10/08/virt...
To give some context on those blog posts; they exist to figure out how to add single inheritance to Rust. One of the strongest arguments for single inheritance in Rust is "Servo and similar things need it to model the DOM". I.e; the strongest argument out there is that modelling cross-language things with languages that _do_ have single inheritance is hard.
That's not a very strong argument. That's a pretty niche use case (which Servo itself has moved past; we have a setup emulating inheritance that works pretty ok now).
So while I do agree that Rust can't model these patterns easily; I'm skeptical that that can be an issue for the large majority of Rust users.
May be there are, but they far from trivial, and with the current level of documentation they are in the realm of some obscure hacks rather than straightforward part of the language. Which is a disadvantage. May be when The Book will cover OOP topics in depth and explain such patterns, or there will be some other dedicated documentation on this topic, things could become more clear.
I don't think so. Rust encourages a certain style of designing code, using enums and traits. Almost all the time this suffices.
My comment was at the macro level; I'm not saying that an OOP pattern will have an equivalent in Rust, I'm saying that if you look at the larger use case you can design your code in idiomatic Rust to avoid it.
As I said, may be you can, but it's far from trivial and unless you know how to do it already, coming up with such approaches isn't something that one who just learns the language would be focusing on. You yourself said above, that it's hard. And unlike languages like C++ where OOP approaches are very well documented, Rust documentation lacks such kind of information at present.
I said modeling single inheritance is hard. That's a very niche use case; basically only crops up when writing an interpreter for a language with single inheritance (and in cases like Servo's DOM)
> unless you know how to do it already, coming up with such approaches isn't something that one who just learns the language would be focusing on
Again, it's not a thing that you do as a drop-in for inheritance. I'm saying that the regular approach (i.e. using traits and enums idiomatically) to designing your application in Rust will cover the use cases for inheritance, differently.
Basically, don't try to write Rust code as if it's C++ or Java and stuff should work out.
That said, the second draft of the book is placing a lot more emphasis on understanding how to write Rustic abstractions.
Then may be there should be one like that :) May be it's just my personal impression, but I feel that such kind of documentation now is lacking.
OOP in Rust shouldn't necessarily focus on comparison with other languages (though explaining key differences would be very helpful). But it at least should explain common use cases that OOP expects the language to cover and approaches that Rust proposes for them.
Something like this would very useful in The Book (or some other book): https://lwn.net/Articles/548560/
When all the soundness holes are closed, then we'll have to evaluate whether it's usable to program in. At the very least, Rust is years ahead here.
Even if those hold up, you have to consider whether rewriting your C++ code to fit the safe subset is actually worthwhile, compared to rewriting in Rust which gives you additional benefits.
It's also evident that Herb didn't bother trying to learn from Rust in the slightest back when devising this tool, see his own remarks on Reddit: https://www.reddit.com/r/cpp/comments/3m0d41/writing_good_c1...
Furthermore, the tool in question does nothing to improve C++'s capability for safe multithreaded programming, which IMO is Rust's actual (yet so often overlooked) ace in the hole.
"The package currently contains checkers for the Bounds and Type profiles. Tooling for the Lifetime profile demonstrated in Herb Sutter’s plenary talk (video at https://www.youtube.com/watch?v=hEx5DNLWGgA) will be made available in a future release of the code analysis tools."
https://blogs.msdn.microsoft.com/vcblog/2015/12/03/c-core-gu...
About 1% of the audience answered affirmatively to Herb's question about who was using some kind of static analysis tools.
Outside HN and Reddit circles, very few C and C++ developers, at least the typical enterprise ones, don't really care about such tools.
Back on my C++ days, just one company cared to pay for Insure++ and I was probably the only one using it.
This is way I am looking forward to use it eventually, but don't have high hopes for wider adoption from other C++ vendors.
I guess need to update to Update 2 when it goes to RTM ready.
So what I'm looking for from Herb Sutter is not just a set of good guidelines and tools to check for them, but also a proof --- or at least an argument --- that if the tool finds no errors in a piece of code then that code cannot be the source of memory safety bugs.
After all, lint was created to compensate for C's unsafety in 1979 and up until clang's introduction of static analysis, barely unused in the industry.
Still C++ isn't going anywhere and is the only native language with first class support in all mobile SDKs, so anything that helps improve its use is welcome.
Nowadays I only use C++ for hobby coding between Android and WP nowadays, or when I need to step out of JVM/.NET worlds, so I missed to follow up on it.
Due to this issue that the rust authors seem unwilling to address, I fully recommend against rust for the precise roles it's intended to be good at.
> Obviously on OOM you usually want to abort _something_. It's just not always the entire thread or process.
Surely you want to abort _some dynamic extent_. The fact that it's (currently) a full C thread is an implementation detail that can hopefully be improved. Requiring manual OOM handling on every single operation is not a scalable solution and will lead to bugs due to laziness or fatigue.
Exceptions aren't necessarily bad/evil. A lot has been learned about the challenges of exceptions/conditions/effects. Language designs will evolve to have better versions of what is a foundational idea in the theory of computation.
In the meantime, a try/catch block is only a small macro over thread::spawn, thread::join, thread::catch_panic away. It would be nice if the language supported that without the weight of a full thread.
i.e. to run rust code that uses the standard library without the chance of abort() on low memory, you need to run it in it's own process.
> you need to run it in it's own process
Assuming that you can detect OOM in userspace at all, which usually isn't the case on Linux (or any other system with overcommit).Anyone want to set up the infrastructure so it's easy to take a library or a .c file and start hacking, and see if you still get a working OS in the end? I suppose part of the problem is defining "working OS" -- I'm not sure I know of any great test suites that check to see that a GNU/Linux distribution continues to in GNUy/Linuxish ways, which is usually what you want for a large-scale rewrite project.
Umm, "smaller"
> incrementally rewrite
It is GNU LibC, even if your rewrite is GPLv1337, the toolchain isn't "free enough" for them. You will be "stopped by verbal force" in the sake of preserving an inferior, but "free" core library.
Apparently we were the fools.
But this will never happen in UNIX OSes.
The culture is married to C, regardless how many memory corruption exploits per days might get a CVE entry.
However I hope to be proven wrong.
Also it makes very easy to recognize reserved keywords.
https://news.ycombinator.com/item?id=11148129
They often have horrible security, but are very small programs when you use them as wifi temperature sensors or similar. They are good targets for rewrites and greenfield applications. Right now it seems like ardunio C++ or some scripting language is the target.
http://www.slideshare.net/master_q/safer-iot-using-functiona...
ATS is a functional programming language that does not use a garbage collector and uses dependent and linear types to do safe system programming. It provides a similar level of safety to Rust with the ability to drop down to C: http://www.ats-lang.org/
I would use Rust for a complete startover. Open source development should shift its mentality to support open hardware. This could ensure safety of both hardware and software in the future, and it would attract many developers who want to contribute.
We already have the tools for open hardware: free IP cores, 3D printers, free CAD, equipment for DIY PCB/SMD boards, etc. ... and Rust for bare bone programming.
Complex runtimes are also unsuitable for libraries. If you write a great openssl replacement in Haskell, it's only useful for Haskell applications. Because nobody wants to link the Haskell runtime into many of the applications that use openssl.
For widespread libraries, the choices are basically C, C++, and now (hopefully) rust.
Rust still has insufficiencies though, the inability to customise the (library's) allocator is one I think.
Iteration without progress is bad.
Which one do you think would happen?
So what I see is iteration with some progress and some regress (wrt to empowering programmers and simplicity). It's good to have a new generation enthusiastic creating their own world, yet if they are as human as previous generation, most likely they would hit the same problems. Like a genetic algorithm, a slight mutation to current solution runs for a certain time and we see how the generation fares. But maybe we need completely different approach to get out of local optima technology seems to be right now. Quantum Rust? ;-)
So your problem is not that a Rust rewrite would be too much of a change. It's that it would be too little? ;)
If there is any popular low-level language that is a "completely different approach", I'd say that language is Rust.
Frankly, Rust just takes a few different approaches known since "forever" and promotes them to 1st class semantic citizens. Similarly Go takes another set. Like every language in existence. So some things will be super easily expressible in one or another language, other things more obfuscated. Yet you could do the same in older ones, but perhaps more verbosely, with more syntactic sugar or boilerplate structures. Hence the comparison to a genetic algorithm with a few mutations in each generation. All a variation of the same set of mental constructs, possibly with very similar descriptive abilities (even when leaving Turing completeness out of the equation).
Anyone downvoting a question care to comment what's so wrong with this?
libcore (the baremetal library) and the language don't need libc at all.
There is the library 'nix-rust' [2], which aims to provide a wrapper of 'libc' in idomatic Rust.
Unlike 'libc', 'nix-rust' does not have a consistent code quality and organization yet. However, Both are missing various bindings for various platforms.
[1] https://github.com/rust-lang/libc [2] https://github.com/nix-rust/nix
Mozilla is paying virtually all of the people who are working on it full-time, but there are a lot of people doing a lot of work in their spare time too.
> with the way things have been going the past few years
If you're referring to the projects which have been dropped over the past few years, I can see that. At the same time, Firefox is the core product, and Rust is already in Firefox, so dropping it doesn't seem likely. The amount will only be increasing.This may well be applicable to kernels and other constituents of an OS.
Chances is successfully going from some not-so-obfuscated C code to equally not-so-obfuscated Rust code?
Why do you want to do that? The only way to make it work short of doing years and years of static analysis research to automatically translate ad-hoc memory management disciplines into those of Rust (that I think will not succeed anyway) would be to compile to unsafe code. And if you compiled to unsafe Rust code, there would be no gain.
Again, this might be a terrible idea, but I'd be curious to hear from anyone that has experience with this sort of porting...
Easy. But it won't be too useful.
Rust isn't a compiler that magically finds memory errors. Transpiling C code to Rust will not find those memory errors unless you have a really good transpiler that can detect the overall structure and design of the C code. It will just give you a ton of Rust error messages; probably none of which relate to an actual memory error. (Or you transpile to `unsafe` rust, in which case, what was the point?).
Rust works with a set of rules, and these rules enforce some things in your programming/software design style. This enforced style (i.e. the discipline around memory usage) is what gets us memory safety. This style is not the same as the style used in programming C/C++; so a dumb transpilation won't work. You need to write a transpiler that can figure out what logic the code (and not just for a function, for a larger unit) was trying to encode, and write that in Rust. That's ... a nontrivial problem to solve with a transpiler, probably requiring AI skills. It's a mostly trivial thing to do as a human, since mostly such "transpilation" involves noticing a few key issues (related to highly-shared structs and whatnot) and fixing them (leaving most of the code the same).
in true.c (all told, an 80-line file):
/* Act like "true" by default; false.c overrides this. */
#ifndef EXIT_STATUS
# define EXIT_STATUS EXIT_SUCCESS
#endif
false.c, of course, contains only: #define EXIT_STATUS EXIT_FAILURE
#include "true.c"
On my current system, each of these represents a stately 27KB dynamically linked executable.By way of comparison, the OpenBSD version of true comprises nine lines with zero preprocessor directives:
/* $OpenBSD: true.c,v 1.1 2015/11/11 19:05:28 deraadt Exp $ */
/* Public domain - Theo de Raadt */
int
main(int argc, char *argv[])
{
return (0);
}(I dimly remember an essay about similar issue in a similar mainframe command (maybe in JCL?) taking a bunch of revisions to actually get right?)
It does seem to me though that if you pre-processed it for a common case and translated it to rust with anything going into unsafe if it has to and started from that you would be off to some sort of start.
The whole thing seems moot though because there are already alternate libc implementations like musl as well as alternate malloc implementations like jemalloc.
I actually still don't understand why libc is the undertaking it is made out to be, especially if you can plug in jemalloc which I would think would take care of the most difficult part.
Could we also drop a lot of requirements that applied to older, more limited hardware? (Or, do certain constrained hardware situations still require most of those requirements to stick around?)
> We can build tools to check C as well as any other.
This is simply not true; language semantics determine the kinds of tooling you can build. Ruby is so dynamic that it's notoriously hard to build tools for, for example.Whatever your opinion of Codes of Conduct, lots of projects have them now. And IMHO not having a Code of Conduct encourages its own sort of toxicity.
There is no silver bullet, just because you use Rust it doesn't mean your programs will be completely safe.
A lot of these C libraries were written in more innocent times where a small bug would not affect as many people as it would today.
We live in a C world and I don't see that changing any time soon.
The same was true of Fortran when C came around. I'm glad K&R didn't use this reasoning in 1978 to justify not rewriting things in their new language.
> There is no silver bullet, just because you use Rust it doesn't mean your programs will be completely safe.
Nobody is claiming that Rust eliminates all security vulnerabilities.
> A lot of these C libraries were written in more innocent times where a small bug would not affect as many people as it would today.
This isn't a positive!
Of course it won't because every time an out-of-bounds array access gives attackers free reign of a system and some one says "hey guys this whole C thing is clearly blatantly terrible" every one else says "Not this crap again. C libraries are not pretty but they have been out there for decades, they have been reviewed and used in production."
As if the libraries have been utterly static for decades and aren't infact full of holes and bugs, which is exactly what brings on the call to rewrite things in Ada/Rust/SML/Lisp
Then they always say "There is no silver bullet, just because you use Rust it doesn't mean your programs will be completely safe." As if there's no reason trying to improve things unless you can jump directly to perfect.
they make excuses like "A lot of these C libraries were written in more innocent times where a small bug would not affect as many people as it would today." as if we still lived in those innocent times.
And then they inevitably wave the call to action off by appealing to the status quo with some line like "We live in a C world and I don't see that changing any time soon." and so even though there's no reason we couldn't start re-writing things (especially in Unix an OS that constantly brags about being built from loosely coupled parts) in a better language we never get a critical mass together.
C's primary design goal that overrode everything else was easy implementation. In order to keep a dumb compiler, the preprocessor was used instead of a proper module system. For the same reasons, the standard library is full of non-reentrant functions relying on global state, unbounded string manipulation functions or bounded string functions with ambiguous off-by-one properties, vaguely defined data types and so on.
If there's one reason to do away with C, is to do away with all the stubborn programmers who clutch their copy of K&R and think everything must be done in the "C way". To paraphrase Linus' on C: you'd want to avoid C just to avoid this type of C programmers. They could be amazing coders, but not if you care about security (and you should).
And with that mastery: what about writing some machine-learning software that detects vulnerabilities as part of the build/release cycle. For instance:
http://news.mit.edu/2016/faster-automatic-bug-repair-code-er...
To detect vulnerabilities people need to be careful and follow best practices. If they can't do that well.. replace the people with software that's better and more efficient than the people. :)
Relying on people being careful does not work for security, where one exploit is as good as many. OTOH, simpler languages can work well for performance, features and almost everywhere else; where even if you don't have specific language features to guard against common mistakes, the impact of an oversight is fairly localized or correctable.
"what about writing some machine-learning software that detects vulnerabilities as part of the build/release cycle"
We've had 44 years for people to master the "simplicity" of C. Turns out, writing C is simple but writing safe, reliable C borders on the impossible even for the most masterful masters who ever mastered their mastery of the language. Better return on investment would be to work on killing C with something that doesn't have C's problems.
Deleted comment