6 ms·
You're right. It keeps on giving us heartbleed, slammer, sasser, kernel null check eliding holes, and literally thousands upon thousands of other memory exploit
by xenadu02 11y ago
You're right. It keeps on giving us heartbleed, slammer, sasser, kernel null check eliding holes, and literally thousands upon thousands of other memory exploiting, remote executing, security breaking bugs.
But I'm sure, Real Soon Now(TM), if teams just adopt (best practices / better libraries / better code reviews / better static analysis tools / better testing) all those problems will be solved and C will be a great language to keep using.
After all, saving a few extra CPU cycles is totally worth breaking all SSL encryption and leaking private keys, quite literally putting the security of EVERY SINGLE FUCKING HUMAN WHO HAS EVER TOUCHED THE INTERNET in jeopardy.
So sure, let's just keep using C. It's fine, why change anything amirite?
(Sarcasm aside: In the general case it is not possible for humans to write security-critical code in C. So far the history of the internet has proven me 100% correct.)
- thrownaway2424 11y agoEvery one of those problems you mentioned occurred in C code, not C++. That might seem like quibbling, but many of those bugs are caused by C memory management bullshit like malloc(that) if (error) goto: free(that), which isn't a problem that C++ has. A scratch reimplementation of OpenSSL in C++ would probably be 1/3rd the lines of code and entirely devoid of both goto and malloc.
- rvense 11y agoAnd a Rust implementation might be half the code and entirely devoid of classes of bugs that might be in the C++.
- quotemstr 11y agoRust's standard library aborts on OOM. That's completely unacceptable. More generally, I find Rust's error handling awkward --- the most common excuse for Rust's OOM handling is "Otherwise, you'd need to cart Result everywhere." Of course. That's why we invented exceptions decades ago. The designers should have used traditional exceptions instead of trying to create something new --- the designers (just like Go's designers) had to go back and add exception support anyway. I'd have liked Rust more if it'd focused on memory safety and less on being different for the sake of being different. I want a memory safe, non-GC language with traditional curly brace syntax, traditional types, and exceptional error handling. Modern C++ is a much better approximation of that language than Rust is.
- dbaupp 11y agoIt's definitely very important for some domains, but handling OOM "properly" is a really vague/impossible concept for most non-bare-metal programming. Modern operating systems will over-allocate/over-commit memory via virtual memory (so malloc usually succeeds), and kill programs when the physical memory limit is reached, and/or just grind to a halt by swapping. For instance, I can happily "allocate" 100 terabytes of memory on my laptop (16 GB of RAM, 16 of swap): use std::{thread, time}; fn main() { let _v: Vec<Vec<u8>> = (0..100_000) .map(|_| Vec::with_capacity(1 << 30)) // 1GB each .collect(); thread::sleep(time::Duration::from_secs(10)); } Of course, if I actually tried to use much of it, bad things would happen, but the point is the allocations themselves never failed. Bare-metal programming, like a kernel, will typically use the lower-level `core` part of the standard library, rather than the whole thing (i.e. `std`) because the kernel will be literally providing the interfaces required for most of std-minus-core. (I think it would be really great if the standard library could be less harsh when an OOM is actually detected, and I suspect it can be tuned in future, but it's not a show-stopper for most tasks.)
- quotemstr 11y ago> handling OOM "properly" is a really vague/impossible concept for most non-bare-metal programming I strongly disagree. Handling memory allocation failure is trivial: throw an exception. It's also trivial to reserve enough memory to throw an exception. I honestly don't understand people who claim that recovering from OOM is futile because you need to almost always allocate memory to recover: in fact, you almost never do. > Modern operating systems will over-allocate/over-commit memory Windows is a very modern operating system and does not overcommit. (To its credit: overcommit is a terrible idea.) Even on overcommit systems, you can exhaust your address space and see allocation failures. No, 64 bits is not actually infinity. No, the whole world is not 64 bit. (Not every program even benefits from being 64 bit --- that's why the x32 ABI exists.) > point is the allocations themselves never failed. The resource you're allocating is address space. When you run out of this resource, your allocations will fail. On overcommit systems, you don't allocate commit charge until you access the memory. It's very difficult to explain to people who work exclusively on overcommit systems that "memory" isn't a single resource, but a set of related ones, each of which can be exhausted. > I think it would be really great if the standard library could be less harsh when an OOM is actually detected The only reasonable thing to do on OOM failure is throw an exception, like Java and C++ do. Error codes are too cumbersome even if you dress them up and call them "monads" --- a lot of code allocates, so if you used error codes to indicate OOM, you'd have to manually propagate exceptions from almost everywhere) and just panicking or aborting is too brittle, since you can, in fact, successfully recover from allocation failure, persistent folk myths aside. Now Rust has both Result _and_ panic/catch_panic, which I think is both sad and hilarious, as it's going to lead to decades of confusion over which error reporting mechanism to use in a particular situation. (The Go designers made exactly the same mistake, as did the designers of the old java.io.File interface.) It's a shame for such a young language to have that kind of baggage already. If Rust's designers hadn't been so stridently anti-exception in the first place, we'd have ended up with a much better language.
- sampo 11y ago> Every one of those problems you mentioned occurred in C code, not C++ The title of the post talks about C, not C++.
- adrianN 11y agoWhile C++ certainly makes it easier to write safe code, you still need to be quite careful. C arrays, manual memory management, dangling pointers and all kinds of other unsafe constructs lurk behind the thin veneer of modern C++ style.
- jernfrost 11y agoNo way, C++ removed some C problems but just added a whole host of its own problems, that don't exist in C: operator overload hell, static initialization and deinitialization hell. Calling virtual methods in constructors blow up. I programmed C++ for 13 years and must have had rose tinted glasses on. I kept reading books like Effective C++ thinking that my bugs would go away as soon as I learned all the intricacies of C++ and best practices. I realize now that I mostly program in other languages that the enormous amount of knowledge you need when writing C++ safely simply isn't needed in most other mainstream languages. If you think C++ is the answer to C's problems I think you suffer Stockholm syndrome. You've gotten so used to all the issues in C++ and started thinking about them as normal, so you stop seeing what a mess this language is.
- thrownaway2424 11y agoNobody is going to make you overload operators, do work in constructors, or throw exceptions. Restrict yourself to the subset of C++ that you prefer. By comparison there is no subset of C that lacks malloc/free.
- sixbrx 11y agoIn practice most of us are restricted to the subsets (note plural) chosen by the people who wrote the original systems we work on.
- ant6n 11y agoBut then you can't move to another language anyway. If you can move to another language (say if you start a new project), it's worth moving from C++ to C++11.
- spacecowboy_lon 11y agoAnd a new language is magically going to solve all the problems you mentioned and do everything c can at the same speed?
- jerven 11y agoNot magically, but with a lot of technical effort Rust does solve those problems and at the same speed. As in a Rust compiler will generate equivalent assembly as C in equivalent cases. With practically for now some places where Rust will win and some where C will win performance wise. But there are no practical reasons for Rust to be slower than C or C++.
- cLeEOGPw 11y agoCould you rewrite linux kernel in Rust?
- wtallis 11y agoYes. However, writing a linux-like kernel that is not 95% `unsafe` code would be a lot harder than just a straightforward syntax change of C to rust.
- kibwen 11y agoSure, but it probably wouldn't make sense to. Instead, you'd be better off doing like the Redox folks and designing your own Rust-based OS, with plans for a Linux-compatible userspace: http://www.redox-os.org/ http://www.redox-os.org/
- pjmlp 11y agoC was dog slow in its early days and there were safer systems programming languages available outside the UNIX world that were equally fast. What has gotten C compilers to generate the code quality that have nowadays is 40 years of work in compiler optimizations targeted to improve C compilers code generation.
- blueflow 11y agoI still wouldn't blame the language for the errors its users commit. Its like blaming Java and PHP for XSS and SQL Injections. Unskilled developers will always write insecure code, despite what language they are using. Edit: To clarify my point, "A fool with a tool is still a fool"
- vpkaihla 11y ago>Unskilled developers will always write insecure code, despite what language they are using. They - uhh I mean - we won't if it's impossible.
- blueflow 11y agoThen explain me how you would make an Language inherently immune to string injections.
- tinco 11y agoYou can make a language inherently resistant to string injections. You only need library authors to cooperate and an extension to your string type like Ruby does, to have your language reject thoughtless injection vulnerabilities.
- blueflow 11y agoIts possible, but if these solution make an language that secure, why haven't them caught on yet? Back to my point: Tools can't replace knowledge. A fool with an tool is still a fool.
- vpkaihla 11y agoAre you claiming that unless we erase all security problems, it was all for nothing?
- deleted 11y ago[deleted]
- srj 11y agoWhat other language would someone use to write a kernel or driver? Even if you use a higher-level language for most of the logic you'll likely want the core to be C -- amazing considering the language is nearly 40 years old. C is, to me, a systems programming language. Writing code that handles any significant amount of user input in the language is a mistake I believe. Note that this doesn't include C++ which has more modern constructs.
- alkonaut 11y agoThat's Rust: it aims to be a viable replacement for C in bare metal and high performance code including drivers, kernels, embedded and all of those areas where C used to be the only game in town. It should do everything C does, but safely and without performance penalties.
- pjmlp 11y agoToday Ada, Rust, Spark, C++, ATS. Eventually Swift, Systems C# (if it ever comes out MSR), D, or any other language.
- mpweiher 11y agoYou might be surprised that NeXTStep used Objective-C for device drivers in the kernel.
- jernfrost 11y agoThat is pretty cool. Shows some of the versatility of Objective-C. I was also surprised that a low level API like Metal also uses Objective-C.
- snaky 11y agoLua http://bsd.slashdot.org/story/13/02/16/2329259/netbsd-to-support-kernel-development-in-lua-scripting http://bsd.slashdot.org/story/13/02/16/2329259/netbsd-to-sup... www.lua.org/wshop13/Cormack.pdf
- bnegreve 11y ago> After all, saving a few extra CPU cycles is totally worth breaking all SSL encryption and leaking private keys, I'm afraid that these few CPU cycles do make a difference. Throughput is the number one concern for thousands of network operators and service providers. They spend millions so you can get your content and not "509 Bandwidth Limit Exceeded". You can't just go and replace all efficiency critical software by something that runs maybe just 10% slower.
- ArkyBeagle 11y agoIt is 100% possible for humans to write utterly secure code in 'C'. The vast majority of practices which make code not open to memory exploits were common in the 1980s - the late '80s, anyway. Yes, there were virii even then. Now, is this common? I have no idea. A great deal of 'C' code never sees the larger Internet anyway.