3 ms·
> Search the Chromium and Firefox bug trackers. Hardly standup examples of good C++ code. Take the latest use-after-free in Chrome to date, namely CVE-2015-67
by nly 11y ago
> Search the Chromium and Firefox bug trackers.
Hardly standup examples of good C++ code.
Take the latest use-after-free in Chrome to date, namely CVE-2015-6765, from the top of[0], The fix for that is was [1], and adds a memory safe standard container (std::set) to keep hold of some objects to change object lifetime. I've looked at it for about 3 minutes and I can tell immediately that the entire implementation of the "appcache update" functionality is a complete hack job. There are variables and calls everywhere keeping track of, and querying, state. There are multiple containers holding objects in different states being manipulated all in the same routine, and this fix adds another. If a "job" can't outlive its "fetchers" then why don't the fetchers own them?
Raw pointers everywhere, this pointers being passed around... "DeleteSoon"... excessive assertions...it's amazing at how much ugly, poorly structured, and scary looking code can be packed in to one file.
I would argue this is a data point in favour of a correlation between programmer skill and frequency of vulnerabilities. Whoever wrote this clearly knows C++, but they don't know how to write good code.
[0] http://www.cvedetails.com/vulnerability-list/vendor_id-1224/product_id-15031/opec-1/Google-Chrome.html http://www.cvedetails.com/vulnerability-list/vendor_id-1224/...
[1] https://codereview.chromium.org/1463463003/diff/20001/content/browser/appcache/appcache_update_job.cc https://codereview.chromium.org/1463463003/diff/20001/conten...
- pcwalton 11y agoIt's very easy to beat up on vulnerable code and say it's "bad C++", but it's also irrelevant. Of course it was bad C++: it was vulnerable code. The problem is empirical and practical. In practice, nobody has managed to scale large C++ codebases up to hundreds of developers without introducing vulnerabilities. You're essentially telling Google "just hire better programmers". That hasn't worked for decades, and it's not going to start working now. The idea of Rust in this regard is quite simple and obvious. Instead of trying to hire better programmers, just have the computer check to make sure these vulnerabilities don't happen. In contrast to the "just hire better programmers" suggestion, which has failed again and again for decades, this works very well in practice, as memory-safe languages have shown. At the end of the day, yes, it's theoretically possible to hire hundreds of great programmers who always write perfect C++ with no memory safety problems or undefined behavior. But in practice it never works. Google is in fact in a better position than perhaps any other organization to do this; if it could possibly work for anybody, it surely would have worked for Google! Rust is a choice grounded in pragmatism. Memory safety enforced by the compiler is the only way that we know of to scale up programs to large codebases with hundreds of programmers without introducing mistakes. "Hire better programmers" may work in theory. In practice, it has been tried again and again and has always failed. (Also, std::set is not memory safe. It is vulnerable to UAF due to iterator invalidation: iterate over a set and remove elements, for example.)
- nly 11y ago> It's very easy to beat up on vulnerable code and say it's "bad C++", but it's also irrelevant. Of course it was bad C++: it was vulnerable code. I'm not just beating it up as "bad C++" per se, I'm beating up the overall thoughtlessness of it all. Introducing a red-black tree, to plug a ownership flaw, is a sign things are dire. > Also, std::set is not memory safe. It is vulnerable to UAF due to iterator invalidation: iterate over a set and remove elements, for example. If you want to do that, then you shouldn't be using an ordered set. Doing so, for some arbitrary predicate, is O(n). Language is irrelevant. Why should the library make doing dumb things easy or safe? (Even though it did make a slight concession in C++11, at zero cost, by returning an iterator from std::set::erase). If someones first thought, when they find a library, which happens to not make something easy, is to shrug it off and write unsafe code, instead of spending 30 seconds re-evaluating their own decisions (whether wrt their own design, or using the library), then I'd say they're not a particularly good programmer. Now if you want to do something sane, like removing a range or an equal subset, then it's trivial of course: // remove 6 through 10, inclusive. s.remove(s.lower_bound(6), s.upper_bound(10)); // remove all the 42s s.erase(42);
- pcwalton 11y ago> Why should the library make doing dumb things easy or safe? Because people empirically do a lot of "dumb things", and it's nice when computers check to make sure that they don't before deploying that code into production. > If someones first thought when you find a library doesn't make something easy is to shrug and write unsafe code, instead of spending 30 seconds re-evaluating their decisions (whether wrt their own design, or using the library), then I'd say they're not a particularly good programmer. OK. Let's say you're right and Google (and every other large company, because Google is no worse than any other) is full of "bad programmers" who have no idea what they're doing. What is your practical solution?
- nly 11y ago> OK. Let's say you're right and Google ... is full of "bad programmers I never said that, so I'm not swinging at straw men.
- archgoon 11y agoWhat's your goto example of good C++ code?