Stories
Slash Boxes
Comments

SoylentNews is people

posted by CoolHand on Friday May 08 2015, @09:01PM   Printer-friendly
from the off-with-its-head dept.

Ladies and gentlemen, the C programming language. It’s a classic. It is blindingly, quicksilver fast, because it’s about as close to the bone of the machine as you can get. It is time-tested and ubiquitous. And it is terrifyingly dangerous.

The author's biggest issue with the C language seems to be security holes:

If you write code in C, you have to be careful not to introduce subtle bugs that can turn into massive security holes — and as anyone who ever wrote software knows, you cannot be perfectly careful all of the time.

The author claims that the Rust language is a modern answer to these issues and should replace C (and C++). It does look that Rust can run C code, so it looks like an interesting proposition. What do Soylent's coders think about this?

 
This discussion has been archived. No new comments can be posted.
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • (Score: 3, Insightful) by bob_super on Friday May 08 2015, @09:15PM

    by bob_super (1357) on Friday May 08 2015, @09:15PM (#180478)

    The overwhelming majority of C programmers will tell you they write safer code than average. They don't need no stinking protective overhead...

    Starting Score:    1  point
    Moderation   +1  
       Insightful=1, Total=1
    Extra 'Insightful' Modifier   0  
    Karma-Bonus Modifier   +1  

    Total Score:   3  
  • (Score: 3, Informative) by pe1rxq on Friday May 08 2015, @09:35PM

    by pe1rxq (844) on Friday May 08 2015, @09:35PM (#180495) Homepage

    I would state it even more generic: The overwhelming majority of programmers will think they write safer code than average. They will manage to write crappy code in any language.

    • (Score: 3, Informative) by maxwell demon on Friday May 08 2015, @11:29PM

      by maxwell demon (1608) on Friday May 08 2015, @11:29PM (#180556) Journal

      It is even more generic: The overwhelming majority of people will think they are above average in mastering most of their activities.

      --
      The Tao of math: The numbers you can count are not the real numbers.
      • (Score: 3, Funny) by naubol on Saturday May 09 2015, @03:55AM

        by naubol (1918) on Saturday May 09 2015, @03:55AM (#180627)

        The overwhelming majority of people think they're above average.

        • (Score: 4, Funny) by dyingtolive on Saturday May 09 2015, @06:02AM

          by dyingtolive (952) on Saturday May 09 2015, @06:02AM (#180649)

          The overwhelming majority.

          --
          Don't blame me, I voted for moose wang!
    • (Score: 3, Insightful) by Nerdfest on Saturday May 09 2015, @12:28AM

      by Nerdfest (80) on Saturday May 09 2015, @12:28AM (#180578)

      True, but some languages *encourage* the writing of code that is insecure and hard to maintain. I've never considered C one of those languages though. Visual Basic, JavaScript, and a few others, yes, but not C. I've certainly seen my share of bad C and wouldn't choose it over some other languages for writing the most maintainable code, but I don't think it encourages the bad habits I see in other languages.

  • (Score: 1, Interesting) by Anonymous Coward on Friday May 08 2015, @09:54PM

    by Anonymous Coward on Friday May 08 2015, @09:54PM (#180507)

    If you want to do a buffer overflow on my last C application, you'll have to enter it using a 4 button keypad and a menu on a 1602 LCD, or pry off the "warranty void if removed" sticker and JTAG it, and then its not my problem. Does rust even run on an AVR?

    • (Score: 3, Informative) by tftp on Saturday May 09 2015, @06:35AM

      by tftp (806) on Saturday May 09 2015, @06:35AM (#180652) Homepage

      If you want to do a buffer overflow on my last C application, you'll have to enter it using a 4 button keypad and a menu on a 1602 LCD

      Sometimes it is enough to keep one button in the pressed state for an hour or two. Chewing gum will do it for you. Correct coding of the interrupt handler and the input queue takes time; time is always in short supply. Are you sure that the queue implementation in your RTOS, or in whatever code that runs in your main loop, is safe and that you are using it safely? Can you prove it?

      I did my share of C coding for AVR, and I had to reinvent all this code more than once. Sometimes I reused my old code. I cannot prove that all of it is safe. I follow best practices, though, and the code is functional. But can it be hacked via an intentional, never occuring in tests, buffer overflow? I cannot say. I just don't have manpower to check for all those "can't happen" situations. I can only say that the code was tested on datastreams that it was supposed to handle.

      • (Score: 2) by VortexCortex on Saturday May 09 2015, @08:32AM

        by VortexCortex (4067) on Saturday May 09 2015, @08:32AM (#180685)

        I can only say that the code was tested on datastreams that it was supposed to handle.

        My meta language can output in C and generates unit test stubs with input fuzzing for numerics and strings based on parameter type or explicit doc comment ///@range[a..b,c,d..e] or ///@random[...]

        There really is no excuse for not testing your code properly if it has anything to do with security.

        • (Score: 2, Informative) by tftp on Saturday May 09 2015, @06:11PM

          by tftp (806) on Saturday May 09 2015, @06:11PM (#180821) Homepage

          My meta language can output in C and generates unit test stubs with input fuzzing for numerics and strings based on parameter type or explicit doc comment ///@range[a..b,c,d..e] or ///@random[...]

          This works great if this is a high level software. However in the examples that the AC and I used you need to generate those test vectors not only across the input space, but also across time. Most embedded systems have global variables. Usually they are protected with some sort of a mutex. Typically they are declared 'volatile.' This works fine in userspace. But it becomes funnier when you enter the land of interrupt handlers. Often you cannot wait on a mutex in an interrupt handler because then the code deadlocks. You sometimes use the {enable,disable}_interrupt() macro to ensure that the usercode touches the protected variables only when interrupt handlers can't... but this is an equivalent of Linux's BKL, and it is bad. What to do if you cannot use this crude "mutex"- say, if you have interrupts that must not be disabled, even for this little, or if you have several levels of interrupts and they can interrupt each other? Then it calls for a more complex interrupt handling, when interrupts of different levels can interrupt lower ones - and this allows to wait in interrupt handlers, as the timer runs on NMI or an equivalent.

          As an example, I have the Schwinn 470 Elliptical Machine. (A very useful thing for a programmer, by the way.) It has at least one bug. If you press the "PAUSE/END" button when it beeps, the incline level drops. I suspect that interrupts from the timer and from the GPIO are not on friendly terms with each other.

          This is not the only catch that you can find in embedded systems. There are other - like hardware that sends you values that are documented as "cannot happen, ever." Are you sure that you wasted precious bytes and microseconds in an interrupt handler, with interrupts disabled, to check for six impossible things? Yes, it is a prudent thing to do. But how many people have done it, after they received assurances from their hardware developers that this here CPLD of FPGA simply cannot output a byte with values outside of the 0x00 to 0x0F ? Are you using this value as an index into a 16-element array, by any chance?

          But of course an embedded programmer with 20 years of experience will spend a single AND machine instruction and make this value safe. Will a junior programmer with three weeks of experience do the same? Will his code be reviewed? Will the bug be found? It's pretty hard to look for bugs in code that is written in languages that have no explicit contract. That byte that we think is in the [0..0x0F] range may be latched in one place, transferred between different pieces of code and different globals, and may end up somewhere where you wouldn't be even checking. You'd have to verify that someone, somewhere ensures that the value is in range. A reviewer sees one module at a time. With tens of such variables, range enforced in various places (or nowhere,) only the code's developer can be reasonably aware of what exactly is happening. Not even him in case of a large codebase, or after a few months of working on another project. Design by contract is possible in C, but only by hand - poorly. Enums can have any int value. Packed structures may have different memory layout on different CPUs, or with different compiler options. Endianness is also somewhere there, lurking in the shadows and waiting to bite you when you are not vigilant. Incompatible types may be freely passed between modules, gaining or losing sign or bits. As memory in MCUs is not exactly infinite, you tend to use uint8 and uint16... but are they sufficient for the task at hand? Why do you think so? Say, the ticks counter will wrap after 240 days of continuous operation. Is this OK or not? What design requirement have you based your opinion on? Does the customer agree? If it is not OK, what have you done to ensure that the overflow is handled properly? Is there is a code somewhere, written by someone else, that checks for a too long execution time and throws an assert() if, when treated as uint32, it exceeds 0x00000FFF? Do you know that this particular runtime implements assertion failure as "while(1) {}" ? It's not an excuse that you never use asserts. A closed source library that your boss purchased may do so.

          As most, if not all of these checks can be done by compiler and by the runtime, it is usually beneficial to spend a bit of excess CPU performance on checking all these things and doing the most reasonable thing if the conditions are not satisfied. Doing it all by hand is possible, especially in C (where everything is possible,) but it increases code size, increases probability of a bug, and increases the cost - while doing nothing at all in normal use. What software manager will approve this work if the VP is breathing down his neck?

    • (Score: 2) by q.kontinuum on Saturday May 09 2015, @09:40AM

      by q.kontinuum (532) on Saturday May 09 2015, @09:40AM (#180698) Journal

      <nitpick>Neither RUST not C nor C++ runs on AVR, that's why we need a compiler</nitpick> However, there is a fork [github.com] of the rust project which will compile for AVR. This was the first thing I checked after reading the article. C is widely used to program operating systems and embedded systems, because most other languages (interpreter languages) need a runtime-environment and an underlying OS.

      I am interested in learning more about RUST. Having a new language for low-level programming, entirely designed with security in mind, would be awesome. However, the other comments to this article mentioning the current instability of the language definition (the same code compiles one week and is broken the next week due to compiler changes), dampened my enthusiasm a bit for now.

      --
      Registered IRC nick on chat.soylentnews.org: qkontinuum
      • (Score: 2, Informative) by mvdwege on Saturday May 09 2015, @07:31PM

        by mvdwege (3388) on Saturday May 09 2015, @07:31PM (#180840)

        Having a new language for low-level programming, entirely designed with security in mind, would be awesome.

        What's wrong with Ada, aside from not being the 'Next Big Thing' praised by all the hipsters?

        • (Score: 2) by q.kontinuum on Saturday May 09 2015, @08:16PM

          by q.kontinuum (532) on Saturday May 09 2015, @08:16PM (#180853) Journal

          I never heard much about ADA, but after seeing your post I started reading about it. Thanks, I guess I will use it for my next AVR project :-)

          --
          Registered IRC nick on chat.soylentnews.org: qkontinuum
          • (Score: 1) by mvdwege on Saturday May 09 2015, @08:51PM

            by mvdwege (3388) on Saturday May 09 2015, @08:51PM (#180860)

            I dabble a bit in it; I'm a sysadmin by trade, programming professionally for me is mostly scripting languages.

            When I do have a hobby project that needs C levels of speed, I go for Ada though (note, it's not an acronym, it's named for Lady Ada Lovelace). It's a nice language, a tad verbose, using words instead of sigils for block delimiters, and it's very much tied up in its philosophy of 'everything is a type with defined behaviours', which accounts for its 'bondage-and-discipline' reputation.

            That aside, it's very elegant and fairly intuitive once you grasp the type system, and it has a really helpful community centering mostly around the USENET group comp.lang.ada. Where, surprisingly, even a hobbyist dabbler like me gets detailed and friendly answers from guys working on massive industrial projects, with zero condescension.

            The AVR runtime is especially good; I have a project on the backburner to hook up some motion sensors to an AVR board and build my own burglary alarm system.

  • (Score: 4, Interesting) by kaszz on Saturday May 09 2015, @12:16AM

    by kaszz (4211) on Saturday May 09 2015, @12:16AM (#180569) Journal

    The majority of programmers perhaps just lack the talent [soylentnews.org] and won't realize it, nor will their management. Because coincidentally they might also be cheap and say yes. Doing the homework [soylentnews.org] perhaps isn't done either. So this is first a cognitive bias failure and secondly perhaps a lack of realization that most people doesn't have what it takes to be a sharp programmer. So to run a code factory with code monkeys the languages are under pressure to adapt to the lowest common denominator.