Slashdot Mirror


The Internet Has a Huge C/C++ Problem and Developers Don't Want to Deal With It (vice.com)

What do Heartbleed, WannaCry, and million dollar iPhone bugs have in common? From a report: One bug affects iPhones, another affects Windows, and the third affects servers running Linux. At first glance these might seem unrelated, but in reality all three were made possible because the software that was being exploited was written in programming languages which allow a category of errors called "memory unsafety." By allowing these types of vulnerabilities, languages such as C and C++ have facilitated a nearly unending stream of critical computer security vulnerabilities for years.

Imagine you had a program with a list of 10 numbers. What should happen if you asked the list for its 11th element? Most of us would say an error of some sort should occur, and in a memory safe programming language (for example, Python or Java) that's what would happen. In a memory unsafe programming language, it'll look at wherever in memory the 11th element would be (if it existed) and try to access it. Sometimes this will result in a crash, but in many cases you get whatever happens to be at that location in memory, even if that portion of memory has nothing to do with our list. This type of vulnerability is called a "buffer-overflow," and it's one of the most common types of memory unsafety vulnerabilities. HeartBleed, which impacted 17 percent of the secure web servers on the internet, was a buffer-overflow exploit, letting you read 60 kilobytes past the end of a list, including passwords and other users' data.

27 of 663 comments (clear)

  1. Developers or Managers? by Terwin · · Score: 5, Insightful

    I expect that there are any number of developers who would be happy to address those issues if their managers would only put enough time into the schedule to do so (and not go-back and demand enough additional features to squeeze it back out of the schedule).

    1. Re:Developers or Managers? by Anonymous Coward · · Score: 5, Insightful

      There is often ZERO ROI for fixing bugs.

      Fixing bugs costs time and money. Clients decide who to go with based on time and money. So, if you spend too much time fixing bugs, your clients all go to your competitors instead.

      You have to cut somewhere, and QA is the juiciest target. Once you win the contract, any bugs that your clients never hit represent money you saved that gave you an advantage over your competitors. Any bugs you clients DO hit but can work around, same deal. Any bugs your clients hit, and that you must fix, represent unexpected costs to you which you can afford because you got the contract. Any bugs you fixed in advance...it's impossible to know if they really needed to be fixed, so they were risks you took that could have cost you the contract.

      If buyers weren't so keen on always going for the lowest bidder, the situation might be different. But as it stands, your business will fail if you spend too much time and money on quality during development.

      So you must release bugs. To succeed.

    2. Re:Developers or Managers? by Spinlock_1977 · · Score: 4, Insightful

      If you need more time to make your c++ code safe, you're increasing its cost. If the business can't bear the additional cost, you're out of luck. Maybe you're using the wrong tool for the job / setting?

      --
      - The Kessel run is for nerf herders. I can circumnavigate the entire Central Finite Curve in a lot less than 12 parse
    3. Re:Developers or Managers? by Zmobie · · Score: 5, Insightful

      While there is some truth to your statement (at least in the managers eye's), this is a very common fallacy. My previous industry saw many companies that had that exact mindset and while in the short term it can work, long term it will guarantee the failure of a company. For every bug, hack, and poor design choice the company is taking on technical debt. Up front, yes, the first and most important thing for new companies is securing jobs/contracts. Therefore one can afford and may even require a fair amount of corner cutting early on to accomplish that goal to establish initial footing (as said many times, no project has an infinite timeline and infinite budget).

      If however that mindset is retained once a company is established the technical debt will accumulate and compounds exponentially over time. It also creates an entrenched mindset (that code has worked for years, no way it broke there!) that makes bug hunting and fixing much harder. Once that becomes the case said company gets a rep for having horrible buggy code that is difficult to fix. It then becomes trivial for the more expensive but higher quality products to take everything over. I know because I watched this exact scenario unfold. My previous employer definitely had their fair share of managers with the speed over quality mindset (I actually wrote a post about that yesterday...), but the overall company strategy was to put out higher quality products than competitors even though it was never going to be cheaper. It worked in spades. They were literally getting jobs to fix other companies' fucked up systems before the installs were even complete because the other companies' reputations got so bad. Keeping that code quality definitely required a lot of fighting between the architects/senior developers and management though (this actually contributed to me leaving that company).

      There comes a break point of cost to profitability where that balance shifts to spending too much time/money on perfecting the software. Older game studios were guilty of that a lot I think (see 3D realms and Duke Nukem Forever), but from my point of view the balance has shifted to trying to put out too much stuff now without properly designing, testing, and fixing the underlying framework. It very much seems to be following economic modeling with supply/demand, but I think we are still in a highly volatile time because so much of the technology is new still (first to market is so valuable to businesses). So overall, I disagree that there is zero ROI to bug fixing and preventative measures, but both are undervalued and difficult to measure their ROI.

    4. Re:Developers or Managers? by Tom · · Score: 3, Insightful

      If you need more time to make your c++ code safe, you're increasing its cost. If the business can't bear the additional cost, you're out of luck.

      So your business can't afford the cost of fixing the code, but it can afford the problems that are caused by that faulty code? Are you sure about that or are you just looking for an excuse?

      --
      Assorted stuff I do sometimes: Lemuria.org
  2. It's not the language, you stupid jackwagons... by Penguinisto · · Score: 5, Insightful

    Nobody blames the 18-wheeler itself if the driver is too incompetent to load or drive it properly under most conditions, and nobody needs to go around blaming C/++, either.

    If you're going to play that close to the metal (let alone doing anything further down, like, say, Assembly), at least try to know WTF you're doing, and get help if you're not sure. The more powerful and flexible the tool, the more dangerous (and less tolerant) things can get for the neglectful, the incompetent, and the ignorant.

    --
    Quo usque tandem abutere, Nimbus, patientia nostra?
    1. Re:It's not the language, you stupid jackwagons... by Luthair · · Score: 3, Insightful

      What if the 18-wheeler were designed in such a way that it was very awkward and painful to check mirrors....

    2. Re:It's not the language, you stupid jackwagons... by iamgnat · · Score: 4, Insightful

      What if the 18-wheeler were designed in such a way that it was very awkward and painful to check mirrors....

      Then it is still up to the driver to be aware of and manage those limitations.

  3. With great power comes great responsibility! by Rick+Schumann · · Score: 4, Insightful

    Guess what? As clever as Python and Java are, you can't effectively write an entire operating system in them, or a high-performance driver like a graphics card driver in them. You could try, but the result would be bloated and slow and effectively useless. So we have compiler languages like C/C++ that require you to actually be a competent programmer who can write code with proper error checking and error handling. I'm not saying that when you have an entire platoon of programmers all working on parts of the same project (vis-a-vis graphics card driver or OS) that there aren't going to be bugs that crop up, but slapping training wheels onto them isn't necessarily the solution to the problem either.

    Note also another 'language' that would have this same problem, and for which there is no substitute for in the highest-performance applications: assembly language. Yes, Virginia, we still use assembly language in some places, so far as I know. Then you really have to know what you're doing.

    Maybe the solution to this problem is to educate and train our programmers more thoroughly and carefully.

    1. Re:With great power comes great responsibility! by AmiMoJo · · Score: 5, Insightful

      Flaws in drivers used to be attractive to malicious actors because drivers ran in the kernel and had immense power. Modern operating systems limit drivers so that the damage they can do is greatly reduced. Also helps with stability because your sound card driver crashing won't bring the whole machine down any more.

      That's the key to security. Assume stuff will have bugs, isolate it, sandbox it, put layers of security in and limit the damage. A bug in the network stack should at worst crash the network stack, which while annoying is far less critical than being able to read parts of kernel or process memory.

      --
      const int one = 65536; (Silvermoon, Texture.cs)
      SJW, n: "Someone I don't like, and by the way I'm a fuckwit" - AC
    2. Re:With great power comes great responsibility! by Anonymous Coward · · Score: 4, Insightful

      Assuming a halfway decent compiler, you could write a graphics driver or a kernel in Rust with little or no performance penalty versus C. You could probably write one in Go. Many have been written in Ada. And I could name many other languages along the same lines. Those are languages that compile down to machine code and can do static allocation and/or explicit dynamic memory management... with static compile-time type checking and pointer and array safety guaranteed.

      Yes, array bounds checks are expensive. However, not that many lines of code actually need to index arrays directly, and especially not with random access as opposed to traversing the whole thing (which can usually be sped up). There are even fewer such cases where the code is on the performance path AND your compiler can't prove what you're doing is safe. And arbitrary pointer arithmetic is still less often needed.

      If you have to do truly unsafe stuff all the time to get performance, you've misdesigned your language, your libraries, your RTS, and/or your data structures.

      In a sanely designed system, on the rare occasions when you really do need to do something unsafe, you either break into another language (yes, even assembly and maybe even C), or you use some specialized construct that explicitly marks the code as unsafe. But maybe one line of code in 100, or even one line in 1000, uses anything potentially dangerous, and you and your tools can easily identify which code it is.

      What you do not do is what C does: have every single line of code potentially full of pointer arithmetic, with the very most common idioms being completely unsafe, not even a concept of a distinction between safe and unsafe constructs, and no protection whatsoever against out of bounds access.

      C's whole approach to pointers, unions, arrays, and most structures is obsolete and basically broken.

      No, it is not necessary to have that kind of power on every line in your main implementation language.

      Maybe the solution to this problem is to educate and train our programmers more thoroughly and carefully.

      Hi, there. I've been programming since about 45 years ago, or over 35 if you only count truly professional coding in institutional settings. I haven't always been pounding out code day in and day out during all that time, but I've written many thousands of lines of code in C and assembly as well as various other languages. I have written drivers from scratch for more than one kernel. I have coded on bare metal with no OS at all.

      I have coded without a safety net. I coded back when compilers in general were really dumb. They rarely noticed when you'd done something obviously idiotic. They never told you you hadn't checked something you should. They almost never optimized out a check you didn't need to make. They offered you few ways to give them any hints about what you were really trying to do. Sometimes they forced you to do dangerous things just because they generated such bad code.

      I have a real CS degree from a top university. I don't tend to take a lot of industry training, because it's mostly crap, but I've been around enough to take a fair amount of it in absolute terms.

      I know all the defensive coding tricks. I seem to have a relatively low bug rate compared to many other coders.

      I think I qualify as an "educated programmer".

      One of the things I've learned from that education and experience is not to expose myself to risks I don't need to take.

      For example, if asked to write a large security-critical system, I'm not wet enough behind the ears to actively choose to stick it all in a single address space and then write the bulk of it in C.

      That's because my education and training have taught me that all humans, including but not limited to myself, are unreliable components.

      It's stupid to put faith in them when you don't have to.

      Python, by the way, is not "clever". It has

    3. Re:With great power comes great responsibility! by Hizonner · · Score: 1, Insightful

      Then how come every single project's C style guide requires you to indent it just so?

      What's really broken is having the humans relying on whitespace (which they DO), and the compiler relying on punctuation.

  4. This is news in 2018? by Anonymous Coward · · Score: 2, Insightful

    Unless you just woke up from a coma from 1993, you should have known about unsafe memory practices in 2018.

    Switching to a new language like Rust might help this problem, but it ignores the enormous cost of re-writing software, library compatibility, retraining, etc. The security of the language is just one aspect of selecting the language, not the only one.

    And it's not as if you get a magic security shield just because you chose a memory safe language. There's plenty of other security problems that are either language agnostic, or made worse by language choice. Memory safety is just one aspect of security.

  5. Quote From The Article by deKernel · · Score: 5, Insightful

    "Finally, we can shift the culture around security within software engineering. When I first learned C++ in college, it was expected that sometimes your program would crash."

    A quote from the article...WTF school is teaching this kind of crap. It would appear that the issue mainly resolves around the teaching practices and not so much the language.

    1. Re:Quote From The Article by Anonymous Coward · · Score: 3, Insightful

      Yes, because it's written wrong. Now learn how to do it correctly. The original problems this article addresses are not a learning experience environment set of problems.

  6. Get good developers if you need C/C++ by Ecuador · · Score: 3, Insightful

    Bad developers can create security exploit in whatever is the language of their choice. Sure, with C/C++ you need to be more careful/experienced because they allow this particular type of bug, but in general where C is used it is possibly for a reason and you can't start talking about Java/Python etc (but maybe Rust?), which might be "safer" for a less good programmer.

    --
    Violence is the last refuge of the incompetent. Polar Scope Align for iOS
  7. Not a buffer overflow by thelexx · · Score: 5, Insightful

    What the author describes is not a buffer overflow. Article is ill-informed click-bait.

    --
    "Gold still represents the ultimate form of payment in the world." - Alan Greenspan, 1999
  8. Ad for Rust (author's employer) and Swift by mykepredko · · Score: 3, Insightful

    When did I first hear about "Buffer Overflow" which seems to be the bug in the author's bonnet? Oh yeah, about 35 years ago when I first started programming in C.

    When I RFTA I was floored by the statement "When I first learned C++ in college, it was expected that sometimes your program would crash." - the author implies that it just happens but that's never been true and I would really be hesitant about hiring a programmer that accepted that his programs sometimes crash.

    He doesn't like C/C++, good for him, but programming in Rust or Swift won't help the security problems out there now or in the future.

  9. It's not a deadline problem (mostly) by sjbe · · Score: 5, Insightful

    I expect that there are any number of developers who would be happy to address those issues if their managers would only put enough time into the schedule to do so

    This would account for a percentage of the problem but your argument is something of a cop out because it ignores all the other parts of the problem. You can give programmers all the time and resources in the world and if they used C/C++ these bugs still occur. People are imperfect and they make mistakes. Many programmers are inexperienced and don't know any better. These problems have been known about for decades and yet they still occur even with projects where there are no time deadlines like many open source projects.

  10. Re:Not overblown by olsmeister · · Score: 5, Insightful

    B)
    ____1) Experienced programmers are expensive.

  11. Python or Java Couldn't Exist w/o C/C++ by Slicker · · Score: 5, Insightful

    It is impossible for those languages with "safe" memory access to exist without underlying languages that can openly access memory and that don't hide the truth of the machine beneath them. It is impossible to build an operating system in Java or Python -- they are made-up realities. They are designed to make computer pretend to work in ways they actually don't... in ways humans find easier to view and work with programming logic.

    C and C++ do not hide the underlying machine because they are made to build the layers that actually allow software to work with the machine. The machine is instruction sequences in memory that manipulate memory -- memory is a singular long sequence of bytes. At the lowest level in any computer, that's what's there. Definitely not Python or Java. Python and Java must be written in either assembly language or a "true to the machine" language like C or C++. I am quite sure without checking that they are both written in C++. In fact C was specifically created to write the first UNIX... It's core is the core of POSIX of which even Windows shares... as DOS was written in C.

    It's truly absurd to blame C and C++ memory unsafety. This illustrates a lack of fundamental understand of how computers work.

  12. Re:Not overblown by NicknameUnavailable · · Score: 3, Insightful

    H) c++ has two types of reference/pointer addressing to further conflate things because it was a hack on c's syntax to begin with - it's entire existence is a hack.

  13. C++ compilers should have a "safe" mode by SpinyNorman · · Score: 5, Insightful

    C++ is really two languages in one: backwards-compatible C and modern C++, and unfortunately there's nothing to stop programmers from inappropriately using low level C features when safer C++ alternatives (smart pointers, STL data structures) would be a better choice.

    The C++ standards body should define a "safe-C++" subset that doesn't allow legacy features like C-style arrays and raw pointers. The compilers could have an option to enforce safe mode and only allow exceptions in sections of code explicity marked as unsafe (#pragma unsafe ?).

  14. And the solution? by ponraul · · Score: 3, Insightful

    Rewrite the everything in their favorite/cool 2018 language, instead of using using the newer features of C++ which are designed to mitigate these problems.

  15. Re:Not overblown by Megol · · Score: 4, Insightful

    What exactly is it Ada can't do but C/C++ can?

  16. Re:Overblown by Zmobie · · Score: 4, Insightful

    I hate this argument and always have. By straight raw number comparison yes C/C++ are faster than most managed languages. Problem is most of the zealots that parrot that don't bother to tell you it is typically only a few milliseconds, often nanoseconds, faster on the general operations (hell there are instances where is is actually slower, though admittedly not as many, Dictionaries are a great example). Even in compound highly abstracted layers of code you might see a 5 to 10 ms difference on the operation if you can manage an apples to apples comparison (which typically you can't unless it is a very trivial operation because the coding style between C/C++ is vastly different than even C#) for a very compute intensive algorithm. Even then, the main reason the execution speed is better at all is because the C++ optimizer is significantly better and more mature than a lot of other languages. As we have seen more improvements to the compilers and optimizers of other languages the gap has closed (even Java and C# are surprisingly fast these days with their respective JITs).

    Even theoretically, the performance hit you're referring to is merely a constant added onto the performance calculations because they are able to perform checks based on memory allocation of the heap in managed languages. Hell, it isn't even a great comparison because C/C++ has to perform scope checks to ensure certain objects are even supposed to be accessing the memory in question that is already allocated to that process. Access violations can still occur in those languages.

    At the end of the day very few users can tell much of a difference between a managed and unmanaged language's program, but error rates are way higher in the unmanaged languages (some of it is general unfamiliarity and learning curve of the language, but even experienced developers will still have higher rates from what I've seen). For general use, I dislike C/C++ for writing programs because of the maintenance factor and how many "roll my own" algorithms that can be required, but I will completely agree it does still have solid and semi-common use cases (embedded systems are ruled by those languages and probably will be for a long time). For me, it comes down to using the right tool for the job, and for a lot of business solutions, a managed language is just more suited to doing the work.

  17. A few milliseconds is forever in computer time by DidgetMaster · · Score: 4, Insightful

    ...Even in compound highly abstracted layers of code you might see a 5 to 10 ms difference ...

    I hate to break it to you but 5 to 10 ms is a huge amount of time when you are dealing with big data. Try sorting a 1 billion row table when each row takes a whole millisecond to get in order. That's a million seconds! For the math challenged out there it is nearly 300 hours!