Secure Programming in GNU/Linux Systems: Part I
LNXPhreak writes "A new article on OSWeekly.com discusses secure programming in GPU/Linux systems in terms of programming talent and requirements. Quote: "A "secure program" is an application that sits on a security boundary, taking input from a source that does not have the same access rights as the program. Such programs include application programs used as viewers of remote data, web applications (including CGI scripts), network servers, and setuid/setgid programs."
I've been both in the position of one of the students who had the thougest times understanding pointers in Pascal, and when I started skipping college and studying C at home I started understanding them really well.
Personally, what prevented me from understanding them back when I was in college was their nature, I didn't understand how it worked. When I started working with C and with heavily sending and returning arrays and values from functions, it only made sense to me when I understood that a pointer was an address, and that for example when you want to send a variable to a function and make it modify it, you have to send its address so the function doesn't have to return a value, but can modify the contents of the indicated address.
Once I understood that pointers suddenly went from mysterious to easy and actually people who tell me about pointers when I say I program in C tell me shit like "so you like pointers, huh?" well I actually do now. I think that pointers are only hard to understand (at least in my case) when the language you're in tries to make abstraction of what a pointer really is (like Pascal) as I think one of the strength of C is that it acts more closely to the reality of how things really get done (in a fashion closer to assembly code, although it's portable) and thus makes it alot clearer. (Disclaimer : I've only been doing C for about a year and most of what I work on is DSP programs, thus I rarely have to deal with strings, otherwise I wouldn't like C that much)
You just got troll'd!
well, people *have* tried
/
http://plg.uwaterloo.ca/~glmclear/research/perlos
There are places where the networks are not touching,and there are places where they are-Boeing's Lori Gunter
Personally I think he's wrong but not for the reasons you mention. What's needed is a "managed" language, not a "modern" language. Managed languages have existed almost since high level languages were invented, indeed, for the most part, we did a bad (if necessary at the time) thing during the late sixties to the mid-nineties when languages started to allow us to do unmanaged things.
Examples of managed languages include Java and C#, Pascal and the Modula series of languages (and Oberon, I guess), not to mention a great many interpreted languages like Python (as you mentioned), BASIC, LISP and its derivatives, SmallTalk, et al.
The first group of languages has performance comparable to C, C++, and Objective C. Some are cruder than others ("classic" Pascal is a PITA to work with, mainstream 1980s versions had to massively extend it to get it to work, frequently ending up discarding management along the way), others, like Java, currently suffer from the way they're currently packaged (but see GCJ), but all essentially prevent you from making basic mistakes and provide a level of code security that, arguably, makes hardware memory protection obsolete.
I'm not going to argue they're perfect. Java suffers from its designers obsessions with discouraging the use of native APIs in the name of half-arsed "portability", and both it and C# require substantial run-times for much the same reason. At the same time, when you use either, the level of security you get is much, much, better, with it being much more difficult for a bug in one piece of code to corrupt another in an exploitable way.
I love C, I really do. I've programmed it since the late eighties. I've amazed myself with some of the stuff I've done. But, with hindsight, while we probably couldn't have gotten here today without the experimentation and lack of restrictions it did for us, it's also the case we've had to end up with vastly inefficient computer and operating system designs and our current problems with security are manifested in our decisions to base our entire computer infrastructures on that language. Much as I hated it at University, with hindsight I think Modula 2 and its object oriented successors would have been a better choice. And now that Java and C# have momentum, it's time to jump on board with both feet.
You are not alone. This is not normal. None of this is normal.
Consider C/C++ something like downhill skis. If you know what you're doing, you can go incredibly fast on racing skis. Hell, you'd be pretty quick on normal skies too but that translates well to novice/pro programmers.
But if you don't know what you're doing, you are a lot more likely to hurt yourself badly on racing skis. Why? Because they're only designed to give you the minimum of control you need to get down in one piece. They will not forgive you the slightest mistake, instead you will crash.
So to if a newbies comes in thinking he'll buy racing stuff because they're so flashy and cool and expensive (and he's got the cash), if you have any conscience you'll advice against it. You'll tell him that using this equipment is unsafe.
C/C++ pointers work the same. Most of the time you don't need that extra bit of speed, 99% of the time it's just about reaching the goal. 99% of the time you're just being unnecessarily unsafe. Personally I wrap most things in a library instead of using another language, I don't deal with zero-termination or buffer overflows.
If that really gives inadequate performance, try redesigning what you're trying to do or the method you're doing it with. Dancing around with pointer arithmetic instead of wrapper classes with offset checks is really a last-ditch resort for me, right before I would seek someone who knows assembler.
Live today, because you never know what tomorrow brings
The string handling functions of the standard C library make it very easy to write unsafe code.
So what?
Secure programming in C tends to avoid using the string handling functions as provided by ANSI and POSIX.
Secure programming in C++ tends to avoid IOS for loss of atomicity.
Secure programming in Perl tends to avoid iterpolation of user-data.
Secure programming in any language tends to involve avoiding the mechanisms that are difficult to verify correctness with.
Indeed: the most secure programming languages are the ones where correctness is easiest to verify- to do so in Java or Perl means verifying the VM and runtime, and to do so in C++ means finding that rare soul that actually understands what kind of nonsense the compiler is doing behind your back.
That is to say that C is one of the best languages to use for secure software- not the worst- simply because it's easier to verify correctness on the whole, than with other languages and runtimes.
The example of the image viewer that reads from an untrustworthy source is an excellent one- the Image viewer can be written in any language they like- and could have dozens of bugs and still not be a security risk if the application were run with a restricted uid and had no file or network I/O access.
This could be done by splitting the application into several parts- one that represents the file I/O, one that represents decoding, and one that blits to the screen. The part that represents decoding is probably the hardest to verify, so it would be limited to pure CPU operations, reading bits from an existing pipe (from the file I/O part) and writing bits out to another existing pipe (representing the blitter).
This approach works well, and believe it or not, in a world of increasingly multi-core and multi-processor systems, it's actually faster.