4 ms·
The paper may be Rust specific, but I found the CVE break down chart on p. 25 interesting. When looking at the percentages of the CVE causes (focused on the 59
by throwaway17_17 3y ago
The paper may be Rust specific, but I found the CVE break down chart on p. 25 interesting. When looking at the percentages of the CVE causes (focused on the 59 bugs classified as those Rust prevents) I got the following:
Out of Bounds Reads => 18.6%;
Out of Bounds Writes => 62.7%;
Null-Ptr Deref => 8.5%;
Use-After-Free => 5.1%;
Type Confusion, Uninitialized Pointer Access, Memory Leak => EACH 1.5%;
I have to wonder about the applicability of these percentages to non-RTOS programming. I find it very interesting that 81% of CVE's are allocated to Out-of-Bound Read/Writes, with writes being the larges percent of those obviously.
Has there been any CVE cause analysis performed and publicly available? If so and the percentages bear out similarly to RTOS's across a spectrum of application/system types then there may be some clear cost/benefit analysis needed at the programming language design stage. Rust is a complex language with a complex type and lifetime system to achieve memory safety, and it is not an uncommon refrain that a simpler 'safe' language would be appreciated by many developers. If 80% of CVE's come from Read/Write errors on array access, then a language that enforces strict memory access semantics, but forgoes the rest of Rust's complexity regarding lifetimes and type system complexity would achieve a very large portion of exploit prevention at a minimal cost.
Additionally, if you prevent Null types in the type system the language would then prevent 90% of CVE causes, again with a minimal amount of complexity.
I'm not certain that the above is correct, if the percentages play out in the large, or that devs would actively switch to a considerably safer, while being simpler language. But it certainly is thought provoking.
- bobajeff 3y agoI'm with you on that. In fact I think it's needed to use something less complex than rust in order to prevent other bugs from cropping up due to misunderstood parts of language. C has some bad things it does by default that lead to terrible bugs. I imagine many of them can be addressed without complex move semantics added to it. Some promising work I've seen in this area had been the adoption of language level allocators in zig and Odin. Many newer languages also have better arrays come with length information. And array languages like APL avoid out of bounds errors. I don't think you have to go full ML style type checker (or borrow checker) to prevent bugs.
- pornel 3y agoA bounds-checked slice type would be a relatively small addition to C, and if adopted, it would make size tracking and bounds checking easier. However, there's generally a strong pushback from C developers against features that have an unnecessary performance overhead. Having reliable bounds checking without run-time cost if a much more complicated problem. Rust uses iterators for this, but that requires generics and specialization, and compared to C, these are big and complex features.
- throwaway17_17 3y agoTo be clear, I don't think there is any hope of implementing any protections at the language level in C, the push back would be exceptionally fierce. Although I do agree that a 'slice' type in the stdlib would not be to much to ask for. My comment was more for consideration in the design of new languages, in particular, the development of the frequently cited as not existing, simple, C-like language with memory safety features. In that case, in a green field scenario, there are a few ways to achieve statically known memory-boundary respecting iteration and general access. Further, there are several existing methods of achieving 'generics'. The real design challenge would be in finding the simplest implementation that does not overly burden potential developers. I am confident that it could be done, but it would take some grave dissatisfaction with Rust (which is currently at the top of the adoption curve in the memory safe, but GC free space) for the proposed language to take off.
- GrumpySloth 3y agoThe problem with slices in C being added in stdlib would be that they really are a generic data type. It would be similar to atomic types. While C++ could just add std::atomic<T>, C needed to add a special construct: _Atomic(T). C++ already has a slice type. It’s called std::span<T>. Porting it to C would probably require something similar to atomics. At which point I guess you may just as well get on with it and switch to C++.
- pornel 3y agoC++ chose not to have bounds checking on span’s operator[] by default. Like with vector, approximately nobody will use .at(). Buffer overflow vulnerabilities are where programmers thought they don’t need a bounds check, so having this as a choice every time, with the safer option looking worse, is working against it. A nice minimal built-in syntax for spans (like Rust’s slices) could be an incentive to keep the bounds checks, and eventually make bare pointer arithmetic stand out as riskier.
- hgs3 3y agoCorrect me if I'm wrong, but the percentages on page 25 are lower then what you listed? Out of Bounds Reads => 10.1%; Out of Bounds Writes => 34%; Null-Ptr Deref => 4.6%; Type Confusion => 0.9% Uninitialized Pointer Access => 0.9% Use-After-Free => 2.8%; Memory Leaks => 0.9%; The most staggering statistic is the out of bounds writes. C23 added variably-modified types which helps [1], but I hope future revisions of C consider adding slices. I quite like Zig slices where a "slice" can be constructed from any pointer+length pair. [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2778.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2778.pdf
- throwaway17_17 3y agoThe stats you listed are for the percentage of CVE causes out of the total reviewed CVEs (109), which includes those CVE causes Rust can prevent and those that are completely language independent causes. I took the stats for those CVEs that Rust is said to prevent, which according to the paper is 59 CVEs. So I took the number of any given cause and took its percentage out of the 59 CVEs that Rust's memory safety guarantees would prevent.
- ngrilly 3y agoIn that list, Rust’s borrow checker only solves use-after-free and memory leaks. The other items in the list can be solved without it (null dereference, out of bounds read and write, etc.). See Zig for example.