Slashdot Mirror


Fix the Bugs, Secure the System

LiquidPC writes: "OpenBSD's Louis Bertrand has put his MUSESS 2002 presentation online, entitled Fix the Bugs, Secure the System. Does an overview of OpenBSD, then explains Format String Ugliness, Buffer Overflows, The Wrong Way to Fix Overflows, along with numerous other things."

116 of 334 comments (clear)

  1. Re:Buggy by doooras · · Score: 2

    that doesn't mean there are 20,500 unique bugs.

  2. Script Kitties by Mattygfunk · · Score: 4, Interesting

    It was a bit tedious flicking through all those slides but the final one did bring a smile to my face.

    1. Re:Script Kitties by Fweeky · · Score: 2

      http://www.openbsd.org/ - the OpenBSD logo is a pufferfish.

      The others will represent the other BSD's; FreeBSD, NetBSD, BSD/OS and MacOS X.

    2. Re:Script Kitties by Pengo · · Score: 2


      Great logo, I love that damn fish.

      Actually, after seeing the Fish logo a little while ago (5-6 months), I thought geez ... those guys are either very arogant SOB's or VERY sure of their software with such claims (turns out they are both!!:) ). Since putting it on an old machine which is now my home nat device, I have been a OBSD fan. Even moved a box into production.

      Cheers OBSD team. :) the logo does help IMHO.

  3. Why not just mark the stack non-executable? by Slash+Veteran · · Score: 2, Informative

    Sure, the kiddies can still twiddle with system calls, but if they can't put _their_ code somewhere where _they_ can execute it, it raises the difficulty level of creating an exploit by an order of magnitude. Sure, false sense of security, blah blah blah, but really, shouldn't this (non-exec stack) be a standard feature of any OS that purports to be secure?

    1. Re:Why not just mark the stack non-executable? by Saint+Nobody · · Score: 4, Insightful

      granted, a non-executable stack makes it significantly harder to exploit a buffer vulnerability, but it's not impossible. you can also put your shellcode in environment variables, in the heap, or various other places. if you wanted to follow your line of reasoning to completion, you'd have to have an isolated code segment, marked read-only, and everything else marked non-executable. of course, then we have the issue of how to handle run-time dynamic loading, and programs like vmware--pretty much anything that gets machine code from a source outside of itself and the libraries that are linked in at compile time.

      i do agree with the idea of a non-executable stack, though. it's just regarded far too often as a panacea for buffer overflows.

      --
      #define F(x) int main(){printf(#x,10,#x);}
      F(#define F(x) int main(){printf(#x,10,#x);}%cF(%s))
    2. Re:Why not just mark the stack non-executable? by gillbates · · Score: 2, Interesting

      A better idea would be to have two stacks - one for parameter data, and another for executable data. This way, an overflow in a variable couldn't overwrite executable code.

      --
      The society for a thought-free internet welcomes you.
    3. Re:Why not just mark the stack non-executable? by YU+Nicks+NE+Way · · Score: 5, Informative

      Standard buffer overflow exploits don't execute the stack. The most common form (so-called single instance exploits) alter the return point from a subroutine so that a particular command (also stored by the malicious code) gets executed. (E.g. in a Unix system, the attacker climbs around until he finds a call to exec, and branches to the exec with a call to /bin/sh in the right place on the stack.) The second most-common form consists of exploits that cause a function pointer to be replaced in a heap variable. Even if these exploits required the insertion of executable code -- and I don't know of any cases where they do -- a non-executable stack won't help against a heap attack.

    4. Re:Why not just mark the stack non-executable? by Tom7 · · Score: 2

      Huh? Buffer overflows don't have anything to do with context switches. They are just an artifact of the typical calling convention used, and the exploit happens entirely in user land. You're right that the code doesn't need to be on the stack, but that's usually the easiest place to put it (if there is some static buffer you're overflowing, you put the code in that buffer as part of the overflow). That's because stack locations are much easier to predict than heap locations.

      Making the stack non-executable would make certain kinds of exploits much harder to write, but it also precludes some tricks that compilers use where they actually do need an executable stack.

  4. Can't wait for this all to get sorted out by Brontosaurus+Jim · · Score: 2, Interesting

    Damn it's tough to code in C these days, keeping track of all the stuff that one needs to to be reasonably secure.

    Not to mention the added overhead of making the system secure from semantic errors. Yeesh, it's a good think I get paid a lot for my C work.

    But that's all okay, becuase (finally) technology, like Java, C# (okay this one sucks but whatever), etc that will help out and provide a truly _secure_ development platform.

    I jsut hope they still pay me as much when this stuff finally gets easy, like it should be.

    1. Re:Can't wait for this all to get sorted out by SteelX · · Score: 2, Insightful

      Yes, it's tough to code in C and still keep things secure, especially for inexperienced programmers. But people developing at the OS level need the speed and performance of C. We can't get that amount of speed with Java, C#, etc. There's always a trade-off.

      Interestingly, there's a C dialect called Cyclone by AT&T which tries to give the best of both worlds. It doesn't allow careless code (that becomes buffer overflows, etc.) but it doesn't sacrifice performance either.

    2. Re:Can't wait for this all to get sorted out by sporty · · Score: 2

      Until you wish to open a file/device. Languages are never truely secure.... programming methods are. People are people and will make mistakes that cause security problems.

      --

      -
      ping -f 255.255.255.255 # if only

    3. Re:Can't wait for this all to get sorted out by sporty · · Score: 2

      Java and C++ make it a little more difficult. C++ if you don't use pointers mind you. But I'm sure a well timed exploit can be made should java try to make a null pointer exception. If the JVM tries to execute some code and an exploit is made so that when the reference is made (which was null), it goes into running an exploit writen in byte code.

      --

      -
      ping -f 255.255.255.255 # if only

    4. Re:Can't wait for this all to get sorted out by Chris+Burke · · Score: 2, Informative

      Sorry, but that ain't happenin. The relevant tradeoff between C and Java isn't speed. It's control. An operating system -needs- to be able to fabricate pointers. C is the right tool for that space just above the need for CPU-specific register programming, where you need fine control over system resources.

      New coding styles, sure. I wish the obnoxious bug-prone coding style of ages pass would just fade out. I wish they'd make the next rev of gcc not support calls to strcpy() (and other security abominations) unless you use the --tolerate-shitty-code flag. But C isn't going anywhere, for system programming. There may be something that can replace it for that purpose, but it will be a language -designed- to be a system programming language (like C originally was). That language is not Java.

      --

      The enemies of Democracy are
    5. Re:Can't wait for this all to get sorted out by Chris+Burke · · Score: 3, Insightful

      But no one actually believes C is a good language?

      C is a great language for the thing it was designed for -- system level (ie OS) programming. It turns out that it is mostly decent (and at least functional) at other programming tasks, and this helped it become ubiquitous.

      Most of the problems in C that arise at the system level are a function of the standard library that it came with. For example, strcpy() should have never existed.

      As to whether or not C is any good anywhere else... *shrug*. Minus easy-to-use regexp's, I think once you learn how to write good C code it can be a "good" language for just about anything. Still, I'm not saying I wouldn't mind seeing Java become more common in applications... So long as I can get a good static compiler and libraries for it.

      --

      The enemies of Democracy are
    6. Re:Can't wait for this all to get sorted out by joneshenry · · Score: 2
      It seems to me strcpy() was meant to be an innate part of C from the start? If you don't care about bounds checking, one of the fundamental C idioms taught in K&R is something like:

      while (*s++ = *t++){ ... }

      This idiom is so seductively terse that I wouldn't be surprised if it was one of the motivations behind what became C's syntax, similar to the influence that my Dog Spot has had in modern Perl. In contrast I believe a language such as say Java would frown on having an assignment being used as the conditional, especially in a syntax where equality is often expressed by ==.

      Unix and C were coded as a reaction to the collapse of the Multics project, initially on quite underpowered machines. Terseness was good, sometimes essential to get things running on limited resources. And the initial environment inside a controlled corporate culture was a lot more secure than having to deal with the Internet. I suspect strcpy() was hardly an unfortunate accident, it was by design.

    7. Re:Can't wait for this all to get sorted out by Tom7 · · Score: 2

      This is totally wrong. It's not possible to overwrite pointers with arbitrary values in Java.

      Certain C++ idioms can make things easier, it's true, but you are always subject to heap corruption vulnerabilities, double-frees, etc. C++ just isn't a safe language like Java is. (Even though I'm not so keen on Java, I sure do wish people would use it or something like it when they purport to be writing "secure" code.)

    8. Re:Can't wait for this all to get sorted out by sporty · · Score: 2

      If you run it as two seperate processes you sure can. have the JVM running some bit of java. if you can figure out where in memory certain vars are, i'm sure another process which would be able to address that specific memory location might be able to corrupt it. mind you, the second process most likely can't be in java.

      so as you see my friend, its not totally wrong unless the JVM kept track of the intergrety of the byte code in memory.

      hard as fuck, but don't be surprised if something like this possibly happens

      --

      -
      ping -f 255.255.255.255 # if only

    9. Re:Can't wait for this all to get sorted out by dvdeug · · Score: 2

      Languages are never truely secure.... programming methods are. People are people and will make mistakes that cause security problems.

      Why do you think programming methods are truely secure? People are people and will make mistakes that cause security problems. But in few languages besides C/C++ will you ever have a buffer overflow. Languages are not panceas; they will not solve every problem, but they are one step to producing more secure code.

    10. Re:Can't wait for this all to get sorted out by Chris+Burke · · Score: 2

      I didn't say remove. Obviously you'd need it for already compiled programs that wery dynamically linked to libc. But when compiling something from source, you wouldn't be able to use strcpy(), gets(), sprintf(), etc. unless you supplied the right switch.

      And of course that switch will never exist, that's why I called the thing --tolerate-shitty-code. :P

      --

      The enemies of Democracy are
  5. The only remaining wish... by __past__ · · Score: 4, Interesting
    The only thing I'd like to see from the OpenBSD guys would be a write-up of the gathered wisdom, in form of a "Code-auditing Howto". Unless everybody starts using OBSD (not due this week, unfortunatly), it would be nice if they would share their knowledge so that other platforms like, say, Linux, could benefit.

    But then I guess producing a high quality operating system keeps then busy enough...

    1. Re:The only remaining wish... by ciole · · Score: 2, Informative

      In the meantime, the best way i've found to identify possible poor security practices in my code is to examine known problems in the code of others.

      Which is my first argument for full disclosure of security issues. Not to mention security changelogs.

    2. Re:The only remaining wish... by Chris+Pimlott · · Score: 2

      Then certainly the OBSD auditers have accumlated an impressive collection of bug-classes that we could all benefit from.

    3. Re:The only remaining wish... by mandolin · · Score: 2
      Unless everybody starts using OBSD (not due this week, unfortunatly), it would be nice if they would share their knowledge so that other platforms like, say, Linux, could benefit.

      As if they'd pay attention. And before you mod that as flamebait, ask yourself why strlcpy() still isn't part of glibc..

    4. Re:The only remaining wish... by Arandir · · Score: 4, Funny

      ask yourself why strlcpy() still isn't part of glibc

      Because if it isn't invented at GNU they won't use it?

      --
      A Government Is a Body of People, Usually Notably Ungoverned
    5. Re:The only remaining wish... by jrincayc · · Score: 3, Informative

      Try the Secure Programming for Linux and Unix HOWTO


      It explains the basics of secure programming and common problems with a variety of programming languages including buffer overflow and many more tricky problems.

    6. Re:The only remaining wish... by dvdeug · · Score: 4, Interesting

      As if they'd pay attention. And before you mod that as flamebait, ask yourself why strlcpy() still isn't part of glibc..

      There's a few huge winding threads in libc-alpha <http://sources.redhat.com/ml/libc-alpha> on this. One answer is:

      These words make sense. The problem with strlcat and strlcpy is that they
      assume that it's okay to arbitrarily discard data for the sake of preventing a
      buffer overflow. The buffer overflow may be prevented, but because data may
      have been discarded, the program is still incorrect. This is roughly analogous
      to clamping floating point overflow to DBL_MAX and merrily continuing
      in the calculation. ;)


      Agree or disagree, the developers of glibc don't find strlcpy to be an appropriate function based on its merits. Trying to claim otherwise is just trying to stir up trouble.

    7. Re:The only remaining wish... by Electrum · · Score: 2

      strncpy() won't null terminate the string if the destination is not long enough, which can cause many other problems later (such as calling strlen() on it).

    8. Re:The only remaining wish... by ahde · · Score: 2

      1) Millions of people are charged the wrong amount

      2) Companies with internet connected databases get what's coming to them.

  6. Re:Buggy by sporty · · Score: 3, Interesting

    Just becomes something does something in error doesn't mean its exploitable. If say the newest OBSD distrib forgot to provide a copy of disklabel, that's a pretty serious bug. You can't do a fresh install. A denial of service? Hardly. If the /etc/services file was missing an entry for httpd, it's an inconvenience, but still a bug.

    Maybe I've been trolled, but thought I'd clear that up. A bug is an error in that a piece of functionality isn't right. An exploitable program or process can be a subset of it... that is, if being exploitable isn't part of the original plan.

    --

    -
    ping -f 255.255.255.255 # if only

  7. Re:Buggy by Jerf · · Score: 5, Funny

    Just searching for 'OpenBSD Bug' on Google Groups retrieves over 20,500 queries.

    Searching for "Brian bug" on Google shows 441,000 hits. Clearly you're 20 times buggier then OpenBSD, so I wouldn't be slinging implied accusations around.

  8. The real problem with OpenBSD by vlad_petric · · Score: 3, Interesting
    ... is definitely neither security nor bugs - it's popularity/acceptance. To sustain my claim, there is no OpenBSD entry in the top requested websites

    What's the point of a rock-solid operating system if very few are actually using it (and of course, that happens because of lacking features)? For a server security is always the second issue - the first being the service provided.

    (I'm definitely exagerating here, so flame me as you like)

    The Raven.

    --

    The Raven

    1. Re:The real problem with OpenBSD by Sahib! · · Score: 2, Insightful

      You may not find that millions of web servers are running on OpenBSD, but if there were some way to keep track of how many of them are protected by firewalls/routers running OpenBSD, the numbers would probably be more impressive.
      I, for one, find that the "secure by default" policy is incredibly convenient for a drop-in firewall solution (and I've done this a few times for various companies).

      --

      I prayed about it, and God said, "Don't do it!" But I thought, "I know better."

    2. Re:The real problem with OpenBSD by zulux · · Score: 5, Insightful

      What's the point of a rock-solid operating system if very few are actually using it

      OpenBSD will never show up on my networks - but every packet that gets to my FreeBSD webserves goes through an OpenBSD firewall. I imagine that a lot of packet are touched by OpenBSD - an we'll never know it.

      --

      Moneyed corporations, non-working 'poor' and criminal prisoners are turning productive citizens into tax-slaves.

    3. Re:The real problem with OpenBSD by zulux · · Score: 2

      OpenBSD can do everything that FreeBSD can so I dont see any point with using FreeBSD for your network servers.


      Haveing an OpenBSD box do everything is perfectly reasonable! I respect that arrangement.

      However, FreeBSD has more of a 'performance' slant than OpenBSD does - just as I trust OpenBSD for security, I trust FreeBSD and it's mature softupdates for file serving performance. I love them both - and the diferances between them in user-land are minor, so keeping my skillset current in both is no big deal.

      I understand the apeal of a unified operating system environment, but I found that variety works well for me. I'm considering adding Apple OS X workstations as well - so you can see I'm a bit odd.

      --

      Moneyed corporations, non-working 'poor' and criminal prisoners are turning productive citizens into tax-slaves.

  9. Secure programming by Kiwi · · Score: 4, Informative
    One of the most common security problems is buffer overflows; the way I worked around this was to write a special string library where the strings had meta data; including the maxiumum length a given string could have.

    One of the problems with secure programming is the inertia in the computer industry; most of the operating systems in widespread use today (The *nix clones and DOS derivitives, these days) we developed in a time when security did not matter; *nix has a crude root-or-not security model and MS-DOS has no conception of security at all.

    Personally, I think the solution is a model which has a real security model, such as EROS. The "audit the code so that it is perfect code without bugs" approach to security does not always work, even with OpenBSD.

    - Sam

    --

    The secret to enjoying Slashdot is to realize that it should not be taken too seriously.

    1. Re:Secure programming by wadetemp · · Score: 2

      One of the most common security problems is buffer overflows; the way I worked around this was to write a special string library where the strings had meta data; including the maxiumum length a given string could have.

      OK, great. But how can we be assured that your string library doesn't have security problems? Somewhere, someplace, memory is getting allocated and bytes are getting written, string copies are being performed, and buffers await overrunning. Auditing code so it is perfect and without bugs does work for security, it just has to take place in the libraries rather than the applications.

    2. Re:Secure programming by glenmark · · Score: 3, Interesting

      ...or take the approach taken by OpenVMS from the beginning: any time a system call needs a string, that string is passed by descriptor. Of course, when the programmer is sloppy and uses null-terminated strings for his own calls, a buffer overflow in OpenVMS would only crash the program. Overflowing data would be discarded rather than executed. It boggles my mind that this flaw in Unix still has not been corrected after all these years.

      --
      *** Quantum Mechanics: The Dreams of Which Stuff is Made ***
    3. Re:Secure programming by rgmoore · · Score: 3, Insightful
      Auditing code so it is perfect and without bugs does work for security, it just has to take place in the libraries rather than the applications.

      But it doesn't really work. It's better than nothing, but if there's one thing that years of security bugs should have taught us, it's that there are always new classes of undiscovered bugs out there. You can eliminate every known bug, but that doesn't guarantee that there are no clever exploits that you haven't figured out but that somebody else has (or will) find out how to use. What you really need is a level of security that's orthogonal to code level security. That can be something like capabilities, mandatory access controls, or even just finer grained control over what the code is allowed to do than Unix's all or nothing model.

      Right now, if I want my computer's CD burning software to be able to set itself at high priority to avoid buffer underruns, I have to run it SUID root. That's insane; it means that a single programming error in what reasonably should be a user accessable program could give somebody complete access to the system. That isn't security, it's a nightmare. We need a system where I can assign that program only the right to reset its own priority, and not complete run of the system. Yes, it's better if the code is audited and potential bugs are eliminated, but a system in which a single bug can completely compromise the whole system is badly designed.

      --

      There's no point in questioning authority if you aren't going to listen to the answers.

    4. Re:Secure programming by Osty · · Score: 2, Interesting

      As far as I can tell it is safer and more programmer friendly in every respect. Even assuming you don't use OO, it can still be used as 'a better C'

      new and delete intead of malloc() and free()

      Those aren't guaranteed to be any more safe. You still have to check the value of a pointer after new, and you still need to make sure you use delete.


      cin and cout instead of printf() and scanf()

      Different syntax, same old problems. In and of themselves, C++'s stream objects are no safer than printf and scanf.


      As for the rest, those have little bearing on writing secure code. In terms of security, C++ is no better than C. Both can be used to write secure code, but you do not get it by default simply because you use C++ over C. It's a design process.



    5. Re:Secure programming by slamb · · Score: 2, Interesting
      [new and delete] aren't guaranteed to be any more safe [than malloc and free]. You still have to check the value of a pointer after new, and you still need to make sure you use delete.

      That's half true. You still have to make sure you deallocate properly (call delete or delete[] appropriately exactly once). But you don't necessary need to check return from new - it throws an exception instead of returning null.

      (This might not be true on all platforms. I think the standard specifies this, but am not sure. You can make a test that ensures this by trying to allocate a ridiculous amount of memory and catching an exception. I actually do test this for a library of mine, but have only run it on Linux, FreeBSD, and HP-UX with default allocators.)

      Different syntax, same old problems. In and of themselves, C++'s stream objects are no safer than printf and scanf.

      Not true. There's an entire class of vulnerabilities that printf and scanf are vulnerable to that cin and cout are not: format string vulnerabilities. I think cin and cout suck, but they are unquestionably more secure than C-style format strings + varargs.

      Mind you, cin with char[] stuff is still vulnerable to buffer overflows. Don't do that. Use a string class instead.

    6. Re:Secure programming by slamb · · Score: 2
      God, I hope not. Exceptions are bad, especially when you're dealing with server-side software that needs to be performant. I much prefer an error code (say, HRESULT, if you're in the windows world), and a smallish error handler (usually reached via a goto, but the goto gets hidden in a macro). Much lighter on resources, and I prefer it. Plus, you don't have to write extra code for functions that don't already throw exceptions, though you'll still need to try/catch exceptions from functions that do throw them (ugly).

      Exceptions are a very handy tool when used correctly. Yes, having to handle an "exception" and a "non-exception" version of the same thing would suck. But when used consistently (and you can make operator new and such have consistent behavior even if you don't like the system's - override them), they eliminate a lot of code. You don't need to handle every error right where it could happen; errors just slide down the stack until they are handled. Programmers are lazy enough that when they have to handle every error right where it happens (many if statements after repeated calls), they don't. So anything that makes error handling easier makes better (yes, more secure) code.

      Performance-wise, I've never had a problem with exceptions. Yes, they play games with the stack behind the scenes...probably not as efficient as your goto. But unless you can show me a situation in which exceptions actually cause a performance problem, I'll continue to think they are much, much preferable to goto (ESPECIALLY when the goto is hidden away in a macro - very bad spaghetti). Remember, exceptions are exceptional - if you are throwing them regularly, something is wrong. The only one I have that's thrown even remotely close to commonly is IOBlockError - basically EWOULDBLK/EAGAIN in exception form.

      Where I don't like C++ exceptions is debugging. Java has very, very good support for following exceptions and analyzing the stack. It's excellent for debugging; I don't even need a seperate debugger anymore - stack traces are all I use them for. C++ can't match that. g++/gdb are absolutely terrible about debugging exceptions. You can't catch one in the debugger. You have very little idea where one came from. If one reaches the top of the stack, the code does an abort without printing much useful diagnostic information.

      In fact, you really should try writing Java code. You'll absolutely hate the performance (if you are doing gotos to get an extra nanosecond or whatever, you'll hate virtual machines). But it does exceptions extremely well, and you'll see they are a far superior way of handling errors correctly. And maybe it will teach you that a few nanoseconds here and there aren't as important as having proper algorithms - differences of seconds or minutes. Basically any little bit of code in Java will execute more slowly than C/C++, no matter what the Java advocates say. But if you do things properly, you can have a larger program that is not much slower - by spending time you would have spent on little things to improve the overall design.

      My point was that simply switching from C to C++ is not enough to buy you security. You might get some things for free, but to truly be secure, you'll still have to code securely. There's no way around that (okay, there is, but it involves moving to languages other than C or C++).

      C++ will be no more than secure than C if you treat it as C. But if you take advantage of the object-oriented constructs, you can (1) remove varargs (format string vulnerabilities gone) (2) reduce code that handles arrays (buffer overflows less likely). In other languages (Java, for example), you can completely eliminate both of these. There are still other kinds of problems - though not so common or so easy to fix.

    7. Re:Secure programming by ahde · · Score: 2

      That's a problem with administration skills. See, Unix has the concept of "groups" -- you can grant some priveleges to some users but not others. Now, the linux kernel doesn't really offer very fine grained device control, but that's an implementation problem, not a design problem.

    8. Re:Secure programming by slamb · · Score: 2
      IMHO, it's poor programming practice to let your errors slide up the stack without doing anything about it until you get to the top level (or any level above where the error happened). The farther from the source you handle an error, the harder it is to determine what exactly caused the error to begin with.

      Yes, if it reaches the top of the stack, you've done something wrong. That happens to me when I forget about an exception altogether in C++. (In Java, you're forced to consider all possible types - it won't compile if your method can throw an exception it hasn't declared as such. Nice feature.)

      At each function, you should make a conscious decision about each exception type: should it be caught or passed through. I've got a surprising number of functions for which passing through is the best solution.

      An example: I have low-level IO stuff (based right on the system calls) that throws IOError and subtypes on failure. I have buffer management code that throws MemoryError on failure (and ensures the buffer was as before - some careful logic around realloc). My high-level IO doesn't deal with exceptions at all: it just passes them through. There was careful reasoning and documentation in each case, but no code.

      In that vein, I prefer a small section of general cleanup code at the end of a function

      With proper exceptions, general sections of cleanup code are rarely necessary. As you go up the stack, objects go out of scope. There are a lot of C++ classes out there (often called "monitors" or "guards") that really only exist for their constructors and destructors. When they go out of scope, they make release a lock, free a pointer, or whatever. No finally clause necessary; it correctly handles both exceptions and normal function exit. There's no possibility of programmer error. Something like this:

      class MutexMon : public Monitor {
      public:
      MutexMon(Mutex &m, bool lockImmediately = true) : m(m), locked(false)
      { if (lockImmediately) lock(); }
      ~MutexMon() { if (locked) unlock(); }
      void lock() { assert (locked == false); m.lock(); locked = true; }
      void unlock() { assert (locked == true); m.unlock(); locked = false; }
      private:
      Mutex m; bool locked;
      };

      When that's a friend class of Mutex and Mutex's lock and unlock functions are protected, you can not lock/unlock mutexes otherwise. So you never will have a problem with a lock not being released.

      (Side note: There's a function for locking multiple MutexMons in a certain order based on where they are in memory (an arbitrary criterium that's constant between threads). Even if all paths out of your code release locks, you still need to worry about deadlock.)

      I have tried Java programming (okay, so it was only for a lame elective class at university, because I was luckily a class or two ahead of all the changes to java. They even changed the AI class and the OS class to use java!).

      Yes, I'm still a student and they've done that here. I also think it was a bad choice, for the OS class in particular.

      However, there does come a point where overhead does matter, and comparing lightweight goto-enabled error handling to heavier exceptions when dealing with server-side work (software that has to scale well, and still be performant), there is a difference.

      I still don't buy that. I just can't think of many situations where you pump out exception after exception in a loop. Yes, they are at many places throughout your code. But those should be the branches that are infrequently taken. If they're not, I have to think something more fundamental is wrong.

      If you have an example program that demonstrates a significant performance difference between these two techniques, I'd love to see it. Otherwise, I don't believe it exists.

  10. Look very closely at that picture by Anonymous Coward · · Score: 3, Funny

    The skeleton in front just left of the middle? The one with a beak and wings?

    That was a penguin. :-)

    1. Re:Look very closely at that picture by Harpagon · · Score: 3, Insightful
      On the shirt which have a bigger version of this picture. You can see more than that.

      • Stripe of right top fish is made of Sun logos
      • Yellow left top fish is covered with Windows logos
      Of course, only the blowfish will not get eaten by the cat (because of its spikes).
  11. Re:You [censored] moron. by Alien54 · · Score: 3, Informative
    "Windows Bug" = 4,290 "Linux Bug" = 5,840 If I leave the quotes off, I get: Windows Bug= 1,540,000 Linux Bug = 1,690,000

    with the same technique, searching for '"OpenBSD bug"' (note the quotes) returns only 93 results.

    but this is only using the same yard stick.

    beat yourself which ever way you want.

    Note that this was google groups, by the way, not generic google search.

    on the generic google search, with quotes, the total results are 352 for "openBSD bug"

    --
    "It is a greater offense to steal men's labor, than their clothes"
  12. Re:*BSD is dying by gnu-sucks · · Score: 2, Informative

    ok, you're just full of it now. Most businesses look at FreeBSD as a sane unix OS. Linux on the other hand is almost communistic. FreeBSD has allways been the better server OS over linux. Every single benchmark I've ever seen proves that. Sad thing is though, newbie sysadmins have this strange notion, due to posts like yours, that linux is easier to use. FreeBSD is simply server-orientated. Just because its not the most popular doesn't mean its not better. Let me further my point: I mean heck, windows is more 'popular' than linux. But who gives a hoot? (hint: whats this new vm for the linux kernel modeled after?) And, this is especially critical in proving BSD isn't dead: Mac OS X uses BSD. Hello! Apple choose bsd for its core, and now Apple Computer sells more copies of a unix-based OS than ANY OTHER COMPANY. More than RED HAT.

  13. Secure programming HOWTO for Linux and UNIX by SteelX · · Score: 5, Informative

    While we're on this topic, this Secure Programming HOWTO for Linux and UNIX might be of interest. It's a pretty comprehensive book. And best of all, it's free! :-)

    1. Re:Secure programming HOWTO for Linux and UNIX by dwheeler · · Score: 5, Informative
      Thanks for the plug! My book, Secure Programming for Linux and Unix HOWTO, is free, and it's open source/free software (GNU FDL).

      I've also just posted my presentation on how to write secure programs; it's the presentation I gave at FOSDEM 2002 last week. Note that these presentations have different (overlapping) goals; Louis Bertrand's presentation is primarily about OpenBSD (e.g., how it's developed), while my presentation is primarily about how developers can develop secure programs. My presentation, like the book, is at http://www.dwheeler.com/secure-programs.

      --
      - David A. Wheeler (see my Secure Programming HOWTO)
  14. Re:*BSD: the pallor of death by gnu-sucks · · Score: 2, Informative
    dude, linux is a patchwork upon patchwork of dirty hacked-together c code from 1995. BSD is a model open source citizen. While linux continues to get closer and closer to the product all linux users hate (Starts with a 'w').

    Linux is for the windows convert. FreeBSD is for the unix convert.

    Linux continues to copy off FreeBSD - just look at the latest VM work being done to the kernels.

    I don't care whats popular - if we went by popularity, we would be saying linux was dead.

    SCREW THE NUMBERS, BSD FOR EVER!

  15. Presentation... by sean23007 · · Score: 5, Insightful

    If this had been converted from presentation-style to an actual webpage, it would have been deemed a big waste of time. Where is all the information? There isn't even anything new here, I already knew everything there, and I've only been using OpenBSD for a couple weeks.

    The only thing there was a long list of titles with no information, old or new.

    --

    Lack of eloquence does not denote lack of intelligence, though they often coincide.
  16. Fix the bugs? by Jucius+Maximus · · Score: 3, Funny

    Why is it that when MSFT does something like stopping to fix bugs and secure systems, we make fun of them, but if it's BSD we look at it as something we can learn from?

    1. Re:Fix the bugs? by Malcontent · · Score: 3, Insightful

      Because we area able to learn from the openbsd team. Their goal is to help everybody build more secure systems. MS security practice takes place behind closed doors and can not help anybody else.

      In the end we will see if MS is able to actually execute their goal. OpenBSD already has.

      --

      War is necrophilia.

    2. Re:Fix the bugs? by Zero__Kelvin · · Score: 2


      "Why is it that when MSFT does something like stopping to fix bugs and secure systems, we make fun of them, but if it's BSD we look at it as something we can learn from? "

      M$ doesn't generally try to fix bugs as much as they try to fix it so that there is the perception that they try to fix bugs. In the end, they are perfectly content to sell highly exploitable systems so long as the ignorant masses will buy them. Witness XP ... should they pull it off the market? absolutely. Will they? Why recall Fords with Firestone tires when people are still buying them and they have agreed that if the tires explode and they die there is no liability on the part of those pocketing the pretty polly?

      --
      Guns don't kill people; Physics kills people! - John Lithgow as Dick Solomon on Third Rock From The Sun
  17. Security: start in education by LoonXTall · · Score: 5, Insightful

    I'm a CS major, and we just got some sample code from the professor to help us on our first project. The very first thing it does in main is have a buffer overflow.

    #define SZ 100;
    char buf[SZ];
    cout << "Enter courses filename: ";
    cin >> buf; // BAM!!


    This is C++! We have the string datatype for this! There's absolutely no excuse for this--especially in code that will be referenced as "good" code by everyone else in the class.

    So anyway, the point of this rant is that security will remain horrible until we start teaching people to write securely in the first place.

    --

    ~~~LXT~~~
    Life is like a computer program: anything that can't happen, will.

    1. Re:Security: start in education by Kidder · · Score: 4, Funny

      A professor's code is not necessarily the best code in the world. I had a professor who used gets() in the example code he gave us and I had to explain the difference between fork() and vfork() to him (well, not much of a difference anymore...) I had another professor whose code had a MAJOR memory leak in it. I politely emailed the professor about it and he replied to the entire class with the memorable phrase: memory leaks are not important anymore.

    2. Re:Security: start in education by pclminion · · Score: 2, Interesting
      So anyway, the point of this rant is that security will remain horrible until we start teaching people to write securely in the first place.

      That isn't the prof's responsibility. He (she?) is a computer scientist, not a software engineer, and certainly not a security wacko. The relationship between computer science and software engineering is kind of like the relationship between physics and mechanical engineering -- the scientists create the knowledge and the engineers put it to use. You can't expect a physicist to design a perfect bridge, any more than you can expect a computer scientist to write secure code. It isn't what we do, and we really don't care about it. Computer science is really more about mathematics than programming; if you want to learn good design practices, take a software engineering course.

    3. Re:Security: start in education by p3d0 · · Score: 2

      The distinction between CS and SE is not (unfortunately) as clear-cut as that. The University of Toronto, for instance, has both Computer Science and Computer Engineering (which, of course, includes software), and the two are certainly not as distinct as physics and mechanical engineering.

      Software is a strange beast. There is nothing else so abstract and yet so directly practical. It defies analogy with other fields.

      --
      Patrick Doyle
      I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
    4. Re:Security: start in education by LoonXTall · · Score: 2, Insightful
      That isn't the prof's responsibility.

      I'd like to see you say that to Bruce Schneier.

      Security sucks IRL. Handing people insecure code that they assume is correct is not the way to fix it. If it is not the responsibility of the person writing the code to make it secure (at least against coding errors like string formatting and buffer overflows), whose is it?
      --

      ~~~LXT~~~
      Life is like a computer program: anything that can't happen, will.

    5. Re:Security: start in education by poot_rootbeer · · Score: 2


      But this is RUDIMENTARY sh-t we're talking about here. If I can't trust a professor to understand why buffer overruns and memory leaks are undesirable, how am I supposed to trust anything that the professor says?

    6. Re:Security: start in education by LoonXTall · · Score: 2
      Another question is of course, if you're CS majors, how come you're using C++ for your first project?

      Technically, it's the first project of the course, which is in the 200-level. However, the 100-levels are taught in Java, so this is the first C++ project for everyone who didn't transfer. (I only ended up this low on the pile because I had never even heard of OOP before college.)

      If it were up to me to define the course description, I'd use Python. Delimiting blocks by indentation forces people to make more readable code, which is easier to grade :)
      --

      ~~~LXT~~~
      Life is like a computer program: anything that can't happen, will.

    7. Re:Security: start in education by saintlupus · · Score: 2

      A professor's code is not necessarily the best code in the world.

      If it was, they wouldn't have to squeak by on a professor's salary.

      --saint

    8. Re:Security: start in education by Steveftoth · · Score: 2

      You're forgetting one very large and important area of computer design work. Computer Systems Engineering. Not exactly software, not exactly electrical, somewhere inbetween. You know, the guys that design the motherboards, and the firmware to go with it. Not the guys that design the power supplys, sometimes the chips. But the guys that connect all the pieces together.

      Actually, I don't think that there should be a software engineering degree. I think that CS should include more courses on working in teams and designing code that is easy for other people to work with. Nobody programs in a box these days. Everyone must work with code that someone else wrote the API for. (which is another thing, every student should have to take a class on API design) 50 years ago when all machines were huge and the program you wrote didn't use any shared libraries this didn't matter. But today, it is almost impossiable to write all the code your program executes yourself. ( I mean not useing any libs, no STL, just your ASM/C/C++ code) . The major exception being embedded dev. At least my embedded dev classes, they made up write all the code ourselves, YMMV.

    9. Re:Security: start in education by jaoswald · · Score: 2

      The question is what the professor is teaching about. A physicist would probably feel comfortable teaching about the elastic response of a bridge member. But he would admit he isn't trying to teach you bridge design.

      The CS professor mentioned at the beginning of the thread probably wasn't trying to teach how to program in a way that is robust to various kinds of errors, including security errors. He almost certainly was not claiming to.

      The problem is when people take the limited knowledge they acquired from the CS professor and apply it in the real world without understanding all the implications of what they are doing. That ain't the professor's fault.

      The world would probably be a better place if more computer scientists had actually written the code that is being used to do real world things, because they would have cared more about abstract properties like "correctness" rather than concrete properties like "compiles, doesn't crash." And they wouldn't be programming it in C.

    10. Re:Security: start in education by Tony-A · · Score: 2

      How big can it be?
      What happens when it *is* bigger than expected?
      32767 + 1 yields -32768
      99 + 1 gives 00 (or :0 or ...)
      What happens if the string is bigger than the string datatype can hold?
      At least the prof put the critical assumption up front.

    11. Re:Security: start in education by ahde · · Score: 2

      Computer science is the study of pointers and algorithms and error recovery. Point and click UIs and cut and paste java APIs have nothing to do with science, and very little to do with computers.

      The problem is the instruction. A degree in computer science should mean you know a bit about computers. ALL languages that hide this from the user still depend on the exact same constructs that c exposes.

    12. Re:Security: start in education by pclminion · · Score: 2
      The world would probably be a better place if more computer scientists had actually written the code that is being used to do real world things, because they would have cared more about abstract properties like "correctness" rather than concrete properties like "compiles, doesn't crash." And they wouldn't be programming it in C.

      In fact, most CS people (I do not mean code-monkeys, I mean hardcore CS people) don't use C. The prof probably made this (excusable!) mistake because he's used to using more abstract, theoretical languages which don't allow this sort of foot-shooting.

      I realize you're agreeing with me here (thank you) but I'll state it again. Computer science is not software engineering, nor is it intended to be. Various people have posted on this thread to the effect of "But CS people go out in the real world and write real code!" This, sadly, is quite true but that doesn't change the fact that CS is, at its heart, a theoretical pursuit. Most CS students don't seem to understand this.

    13. Re:Security: start in education by jaoswald · · Score: 2

      No, the problem is not in instruction.

      When one is doing *engineering,* as opposed to typical software development, the person doing the engineering has the responsibility to make sure that they are applying their expertise according to best known practices. If they don't have enough knowledge, they shouldn't do it. An engineer building a bridge without knowing enough about bridge building would be seriously liable for any damages caused. His professor would not be.

      Notice that slashdot rarely has discussions on how Microsoft medical devices have more bugs than Linux medical devices. Because people who program with human lives on the line take their job pretty damn seriously. Because there are serious consequences for failure.

      Coding on the net has no accountability or consequences for failure. That is not a product of poor instruction, but of the commercial nature of the net.

  18. Re:Why is this code bad? by Sivar · · Score: 3, Informative

    strcpy (dest, input); /***WHAM!***/

    Here the code copies the input string to the destination, regardless of what size the input string is.

    if (strlen(dest) => MAXLEN) {}

    Here the code checks to see if the input data is larger than the buffer that it is being copied to, which is great and all except that it is being done AFTER the cpy took place. It's like drinking a bottle of clear liquid in a chemistry lab and THEN checking the label to see if it's sulfuric acid.
    I'm no C expert either, so I may have missed something.

    --
    Computer Science is no more about computers than astronomy is about telescopes. --E. W. Dijkstra
  19. String is not a data type by wiredog · · Score: 2
    It's a class. OK, a class is a sort of type, but it's not an intrinsic type.

    That said, yeah, he should use cin.getline().

    Hey, at least he used #define to set the array size. Wait until you get hit with a 100,000 line program to modify where the author didn't use #define...

    1. Re:String is not a data type by Rupert · · Score: 2

      Actually, it's a template.

      string is a basic_string of char

      and that's about all the STL I know.

      --

      --
      E_NOSIG
    2. Re:String is not a data type by spike666 · · Score: 2

      oh i think you know many more things that are Slower Than Light.

      the length of time it takes managers to make a decision for example.

      or, the length of time it takes a gaggle of geeks to decide where to eat lunch.

  20. Secure the system: get rid of C by Tom7 · · Score: 3, Insightful

    I can't believe there is not one mention of using a language other than C. Is it the systems community? Is it because of BSD's history?

    I don't know why this idea fails to even come up. Network servers are bandwidth-limited, not cpu limited, and writing them in a safe high level language is not only easier, but makes buffer overflows impossible. Being easier to write also of course allows more time for optimization and for other security fixes. (For those that need really high-performance for their gigabit links, maybe a C version and very careful maintenance is possible. For home users, this prospect is ridiculous.)

    C seems almost *designed* to allow for buffer overflow exploits. If we want secure programs, we should be starting from more secure foundations!

    For more detail, check my previous rant, "C lang remains inappropriate for network daemons": http://slashdot.org/comments.pl?sid=24271&cid=2629 013

    1. Re:Secure the system: get rid of C by Tom7 · · Score: 2

      I'm not suggesting ada. Not all safe languages are as perverse. However, if indeed new language ideas are too hard to learn for C programmers, then Java is a totally appropriate choice. (Personally I prefer more powerful and more efficient languages, like say SML.)

    2. Re:Secure the system: get rid of C by Laplace · · Score: 2

      A language is only as good as its compiler. I remember reading an article (at the register maybe?) about a microsoft security product that had buffer overflows not because of the original code, but from the code that the compiler generated. C, not being a very high level language, is easier to write compilers for. It is easy to audit and verify. It is what most system programmers cut their teeth on. All of those reasons (and many more) make it an ideal OS language. Yes, it has its problems, but at least you know that a buffer overflow is your own damn fault if you write it. And with a little knowledge and forethought they can be easily avoided.

      --
      The middle mind speaks!
    3. Re:Secure the system: get rid of C by Tom7 · · Score: 3

      I agree with you in theory, but in reality we have seen very few compiler flaws and very many application flaws. Writing compilers for high-level languages isn't all that hard, anyway.

      I disagree that buffer overflows can be easily avoided. If they are so easy to avoid, why do we continue to see them? Practically every popular network software written by anyone has fallen to a buffer overflow at one time. I also disagree that C code is easy to audit and verify. Wu_FTPD is over 24,000 lines long, and I can't imagine ever trying to think through the security of such a large system on pure willpower. Safe languages give you the benefit of computer checking, and this frees up your mind to think about more important things (such as the security problems that compilers can't check!)

    4. Re:Secure the system: get rid of C by NonSequor · · Score: 3, Insightful

      Somehow I knew someone would say something like this. Which do you think would be easier: making sure that a compiler generates safe code, or making sure that no buffer overflows, memory leaks, or any other such things are in ANY programs or libraries. Why not fix things once rather than having to fix them everywhere?

      --
      My only political goal is to see to it that no political party achieves its goals.
    5. Re:Secure the system: get rid of C by renoX · · Score: 2

      He meant C is inappropriate for SECURE network daemon.
      If you look at the number of security bugs in each software, he's probably right..

      Ada or Modula3 would be interesting I think..
      But overcoming the "network effect" to choose a language will be very hard..

    6. Re:Secure the system: get rid of C by Salamander · · Score: 2
      Network servers are bandwidth-limited, not cpu limited

      Not to detract from your main point, which is a good one and well made, but that particular statement is pretty dubious. Some network servers are bandwidth-bound, some are CPU-bound, some are memory-bound or disk-bound, some are crappy-API-bound, some are bound by complex synchronization/serialization requirements. Most are affected by more than one of these limitations, and by the tradeoffs that must be made between them.

      None of this refutes your argument that C is not the best language for servers. Its lacks of type-safety, range/bounds checks, proper overflow handling (which requires exceptions), garbage collection and so on are all well known. Java is a much better language in these regards while still remaining fairly familiar, and even for completely CPU-bound programs there's a compelling argument for HotSpot-style JIT as an alternative to traditional compilation. If only Java supported true MI instead of the inadequate "interface" hack/substitute (and I do understand how the requirements for code mobility made that a reasonable choice at the time). Other, more "exotic", languages such as those in the Scheme or ML categories might appeal to purists, but their chances of achieving widespread adoption will remain almost nil until the "impedance mismatch" with declaratively-oriented system programming interfaces is lessened.

      --
      Slashdot - News for Herds. Stuff that Splatters.
    7. Re:Secure the system: get rid of C by Tom7 · · Score: 2

      Well, I did it for FTP (in SML) at least:

      http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/tom 7misc/net/mlftpd/

      In fact, it was very easy -- it took me about a weekend to get it working, and then a few days of tinkering to polish it off. That included writing an MD5 crypt library, and mechanisms for writing network daemons that I intend to re-use for later projects.

      I don't know why it is, but there is this sort of gut reaction that the slashdot crowd has about this kind of stuff (maybe it comes from UNIX's history). Since it's not written in C, it is seen as somehow inferior. Even though it supports 99% of the RFC (I would finish it off if people cared..), is 100% buffer-overflow free, much shorter and elegant than C alternatives, open source, etc...

    8. Re:Secure the system: get rid of C by Tom7 · · Score: 2

      > Not to detract from your main point, which is a
      > good one and well made, but that particular
      > statement is pretty dubious.

      OK, you're right. I guess I what I really meant to say is, "For the home user with a powerful computer and relatively small bandwidth, CPU performance of network applications is nowhere near as important as security is."

      I still think SML or O'Caml could take off with hakers, but I'm still trying to figure out a way to convince them to try something new. It's really not that hard, and the interfaces to system libraries are actually rather straightforward.

    9. Re:Secure the system: get rid of C by Tom7 · · Score: 2

      The JVM is probably written in C. Java the language doesn't suffer from all of these problems, just particular implementations may. (There have been security exploits based on bugs in the JVM before, yes.)

      When I say that a language is safe, I mean that the definition of the language doesn't permit "undefined behavior" (where in the case of a C buffer overflow, this leads to running of arbitrary code by an attacker). Java falls into this category. So does SML. Perl and Python do, too, though it is hard to say because they are only defined by their implementations. (So it is hard to separate the language from implementation.)

      Perl and Python, because of their ability to execute commands on the system so easily or interpret code sent by an attacker, are subject to a different class of security holes. Because Perl (especially) attempts to make so much functionality available to the user, it often leads to hack-job scripts that are difficult to reason about. It is true, though, that these languages are "safe" in the sense that they don't permit crashes (that could lead to execution of machine code).

      Why is it unfair to mention that perl has had oveflows? I merely want to challenge the notion that slashdot folks seem to have that buffer overflows are an easy thing to avoid, and that they're only made by "bad" programmers. How can you say that "apparently they're all gone now"?

      Some safe languages (or, say, natively compiled Java) don't have virtual machines. As far as I know, it's difficult to have a bug in a compiler that leads to exploitable security holes. It is certainly possible, but would take a much stranger situation than the ones that typically cause buffer overflows in C programs! And of course, fixing the compiler would fix all of the programs written using it automatically. (Well, after recompiling. ;)) Finally, C compilers also are subject to this "problem", so it has an equal disadvantage anyway.

      As for source code, I'm pretty sure there are open source implementations of the JVM. I am not a big java fan, myself. Yes, I have the source to my SML compiler.

    10. Re:Secure the system: get rid of C by ahde · · Score: 2

      True, java, thanks to its garbage collection, etc. doesn't have problems with buffer overflows and memory leaks. But what it does have is memory waste. It isn't leaking, but you need a lot of space for that garbage collector to work efficiently. And if you don't have it, you run into the same kind of problems a poorly designed VMM runs into when it has to start swapping. Think of the old DOS defrag program. A Java heap gets that ugly alot quicker.

    11. Re:Secure the system: get rid of C by Tom7 · · Score: 2

      > Perl the language ...

      > Because, being implemented in C, so has the JVM,
      > no doubt. But you were claiming that Java is
      > safe, and Perl is not.

      The problem with this statement is that the perl language is essentially defined by its implementation. Therefore "perl" (the language) and "perl" (the program on my computer) are rather hard to distinguish. When I said that perl had buffer overflows, I was referring to the implementation. Of course, a JVM (at least one that doesn't do JIT compilation) is a lot simpler than the perl interpreter...

      > So Java is more secure because it makes things
      > more difficult?

      Yes, actually. It makes certain things more difficult, which is bad for scripting tasks, but good for security. Personally, I believe that outside a scripting domain (and this does NOT include programs that run websites), it should be difficult to execute commands on the system or otherwise run code from the user input.

      I personally have exploited several perl-based web scripts. Just as buffer overflows are easy to make in C, these kinds of bugs are perhaps even easier. (For instance, shelling out to the mail command with a user-supplied e-mail address on the command line.) I know and you know that there are ways to avoid this; the point is that the language makes it easy to do.

      I guess I can say "Java is more secure" and you can say "Perl is more secure" all day. I doubt anybody has done a study. But I conjecture that there have been far more exploits of perl scripts than java programs.

      > How can anyone say there are no overflows in the
      > JVM? I can't see the code, or the development
      > process, therefore my trust level is fairly low.

      You can see the code to the JVM. There are a bunch of open-source implementations. Or, you can compile to native code with one of the many open source native compilers.

      Finally, I'd like to point out that we're working on a solution to this problem, though it's not really mature enough for me to suggest that people use it yet. You and I both keep bringing up that parts of the system written in low-level languages can't be trusted -- the idea is to make trusted low-level languages, in the form of typed assembly language. With this, compilers compile to native code, but provide type annotations that another program can use to verify that the code is safe. The verifier is very tiny, and it would be feasible to prove its correctness. In this scenario, there is no virtual machine to trust, and we don't need to trust the compiler any more because we verify its output.

      We're pretty close to having certifying compilers done for some nice high-level languages. (A few exist already for safe C variants.)

      Here, check it out:
      http://www.cs.cornell.edu/talc/

  21. Fixing buffer overflows by *ptr EBP by redelm · · Score: 3, Informative
    Granted good programming practice [fixed length buffers] is the best solution. But while waiting for code clean-up, wouldn't it be a fairly simple fix to wrapper the offending variable-length libc calls with fixed length calls? The problem is how long a length.

    For x86 with standard stackframe setup, there is an answer: length _MUST_ be less than (EBP - *ptr) if the stack isn't to be trashed. Note that other local data may well get trashed. But at least the pgm doesn't lose control.

    The wrapper could drop early chars or trailing chars, but should signal an error in the unlikely event the code has been made with error trapping. Of course, this wouldn't work if the code was compiled with -fomit-frame-pointer [or equivalent], but there is a price for security.

  22. Performance and C by Tom7 · · Score: 4, Insightful


    I don't agree with your assessment that safe high-level languages necessarily perform badly. (What is the difference between speed and performance?) But, let's forget about that.

    What is "OS-level" about an ftp daemon? BIND? Mozilla? Gnutella? All sorts of network (and other) applications are written in C, even though there certainly isn't any need for performance or device-level bit manipulation. (At least, I would place security way above performance!)

    Cyclone is actually from Cornell, by the way. It's a good project for moving systemsy people away from C, but there are already mature programming languages that are not slow, and yet are secure by default. (Try SML or O'Caml, for instance.)

    1. Re:Performance and C by renoX · · Score: 2

      Disclaimer: please language zealots avoid this thread, it's about choosing the best tool for having secure programs not about religions.

      I've read many good things about O'Caml (nearly as fast as C!), so I tryed to read an online book to learn the language, but I've failed :-( (even though the paper was in French and I'm French)..

      Why? Too different from a "normal" C-like language: I find functionnal-type programs unreadable..

      I know with O'Caml you're not really restricted to functionnal style programs, but the paper was pushing this style quite strongly.

      I like using C, C++, Java (well I don't like Java but I have no problem using it), Perl, Ruby, Python..
      But I can't grasp O'Caml..

      So I'm not really sure that O'Caml (and the other functionnal language) would have a great success replacing the C-like language, maybe Ada or Modula would be easier "replacement languages".

    2. Re:Performance and C by Tom7 · · Score: 2

      Not really. Parsing is easy in high level languages, especially for text-based protocols like FTP, HTTP, and Gnutella. Perl is not special in its ability to manipulate strings! Arranging data is usually easy, too. I challenge you to check out my SML code for an FTP daemon and tell me where it is awkward because of the need to parse data (in fact, I think it is far more elegant than the C version!):

      http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/t om 7misc/net/mlftpd/

      All the FTP parsing code is in ftp.sml.

    3. Re:Performance and C by Tom7 · · Score: 2

      Well, I'll agree with you there. ;)

      I guess my point is, high level langauges exist that make writing network applications easier. Even Java, since it has garbage collection and value-semantics strings, is certainly easier than C.

      > But you need to get the data to C to do anything
      > usefull with it in most cases anyway.

      Well, this is true, but you can encapsulate these in libraries and never think about C code. Still, wouldn't you agree that the more code written in a high-level safe language, the better? (At least for security reasons?)

    4. Re:Performance and C by Tom7 · · Score: 3, Insightful

      No, I'm not nuts!

      I can saturate my 100 megabit link and not go above a few percent of processor usage using my SML FTP daemon. The bottlenecks are definitely the disk and network. (I am using the system call to copy file descriptors, anyway, so that part happens just as fast as the C version.) Honestly, I would estimate that my server uses at most 30% more processor time than wu_ftpd. If I actually thought that was slow, I'm sure I could bring it within 10% without much effort. If you think I'm wrong, you're going to have to give me some evidence.

      For the vast vast majority of users, nobody needs even close to 100 megabits. For the people runing cdrom.com, or whatever, well, maybe a high performance ftp server is in order. These people hopefully have someone who can maintain it and keep up to date on patches. But for the 99.99% of users who install linux and the default FTP server on a sub-100mbit link (ESPECIALLy home users), the security liabilities of the C version far outweigh the imperceptible speed difference.

  23. The fundamental problem... by Anonymous Coward · · Score: 2, Insightful
    ...is that C was intended to be a systems language used by experts. Instead it's being used to create networked systems, and very often by very non-expert coders.

    If you want to make sure people don't make a particular mistake, make it impossible for them to do so. That means you either 1) fix C to eliminate all buffer overflow issues (impossible, IMO), 2) enforce proper coding technique, possibly through a special string library and/or macros (very difficult on a project as large as an OS), or ditch C completely (virtually impossible given the size of the Linux code base).

  24. Wrong!! by Tom7 · · Score: 3, Informative

    What? I don't think you know what you're saying. In any modern operating system, it's not possible for one process to write over the memory of another. Furthermore, saying that this is a Java exploit when it necessitates another process in another language is totally missing the point.

    If a hacker exploited one process this way, then why would he bother to exploit the java program rather than just execute whatever code he plans on executing?

    You are still totally wrong and I WILL be surprised if something like that happens.

  25. C/C++ should have a native string datatype. by Otis_INF · · Score: 3, Informative

    The reason for all this bufferoverflow crap is that in C, and thus also in C++, people tend to use arrays or blocks of allocated memory to represent strings. What's needed is a string datatype IN the language, like int and char. Then, the compiler can do as the CLR does: allocate the strings, even local scope ones, on the heap. This way, no buffer overflows can happen, since the type is in fact a black box, so the overflow will cause some kind of error, plus the overflow can't be used to modify the stackframe and thus the returnaddress, since the string variable isn't allocated on the stack.

    In C++, there is the string class in the std lib, but it's not native to the language. (almost native ok, but not totally like in C#).

    C is a language where the respect for the borders of a block of memory is in the hands of the developer. Clearly, that's too old fashioned today, since languageelements can prevent mistakes C allows developers to make.

    --
    Never underestimate the relief of true separation of Religion and State.
  26. Re:You [censored] moron. by snake_dad · · Score: 2
    with the same technique, searching for '"OpenBSD bug"' (note the quotes) returns only 93 results.

    Ofcourse this is a hit on a newspost containing the quote "I did some OpenBSD bug research, and found that there are none". One reply states that "OpenBSD bugs are dying" and the other 91 results are AOL "me too" replies to the first post.

    --
    karma capped .sig seeking available Slashdot poster for long-term relationship.
  27. Quite stupid reasons by ^BR · · Score: 2, Insightful

    Since strncpy() does exactly the same thing, just don't bothering always NUL terminating the resulting string.

    Data discarding can be detected by checking return values, you can't do much against people not checking the result of their call. The question is, what API is the less troubling ? strncpy() or strlcpy() ?

  28. It is appropriate! by Pinball+Wizard · · Score: 2
    The problem with strlcat and strlcpy is that they assume that it's okay to arbitrarily discard data for the sake of preventing a
    buffer overflow.


    A function should always throw out data that doesn't match its parameters. If a function expects an int and the user passes a double, it gets changed back to an int. The user's data gets lost, but thats his fault for using the program incorrectly. Every C compiler known to man behaves this way. Why should strings be any different?

    --

    No, Thursday's out. How about never - is never good for you?

    1. Re:It is appropriate! by scrytch · · Score: 2

      > A function should always throw out data that doesn't match its parameters.

      No, it should signal an exceptional condition. Checking the return value of strlcpy or strncpy for "actual bytes written" means checking it against strlen ... scanning the string just to get the length. If I could simply get a return value that indicated success or failure, that would be infinitely preferable in my codew. Not that C has strings anyway, it just has some array hacks to deal with moving around what amounts to void* chunks, and not even efficiently at that.

      --
      I've finally had it: until slashdot gets article moderation, I am not coming back.
  29. Learning functional programming by rjh · · Score: 3, Informative

    Learn it in Python. Really. Python 2.2 offers a whole host of lovely functional-programming features. Continuances, even. :)

    I prefer to write functional code in LISP or Scheme, but I won't sneer at someone who uses Python functionally. It might lessen the learning curve for you, let you experiment around with functional programming, and then use what you learn there in Scheme, LISP or Ocaml.

    1. Re:Learning functional programming by renoX · · Score: 2

      I have no problem using functionnal style in Python or Ruby because the "environement" is declarative.

      So using functionnal style here and there is not difficult, and it is used even more in Ruby than it is in Python.

      But it's reading "pure functionnal programs" that I find very, very hard.

      Unfortunately whereas O'Caml is nearly as performant as C (compiled O'Caml of course), Ruby is much slower..

      I tend to prefer Ruby to Python but both are really equivalent.

    2. Re:Learning functional programming by Tom7 · · Score: 2

      I think you mean, "continuations". ;)

      I am glad to see where python is going; it seems to have a rather clean design, and they like to take good ideas out of the programming languages community. But it is still "just" a scripting language; its semantics preclude an efficient implementation (and make it harder to develop large programs).

    3. Re:Learning functional programming by rjh · · Score: 2

      Continuances, continuations, collectors, whatever you want to call them this week. :) Diehard Schemers and LISPers tend to call them collectors, after the way they're called in The Little LISPer and The Little Schemer, other people call them continuations, and in Python I've seen them called continuances. Go figure. :)

      I wouldn't be anywhere near so quick to decry Python as "just" a scripting language, by the by. I've found that with a little care I can get Python's speed to just about equal native code. I write the entire app in Python, then profile the code to see the bottlenecks. I open the bottlenecks up algorithmically when I can, and if they're still performance limiters I implement them in C++. I've been very pleased with the results so far.

      Insofar as "its semantics ... make it harder to develop large programs", I can only believe you've never used Python for a large program. Compared to C or C++, Python is a gift from above.

      I have a very warm spot in my heart for Scheme. But I don't feel the biggest advantage of functional programming languages comes from speed of execution (although it competes with C/C++), or from elegance (LISP = Lots of Idiotic Stupid Parenthesis), or from scalability. The big strength of functional programming comes from the way it forces you to think about the problem--it forces you to think about the problem in an extremely formal way, as opposed to the ad-hockery that passes for C. There tend to be a lot fewer bugs in my Scheme code than my C++ code, and hence tend to be a lot more reliable. Mostly, I think, because of the impressed formalism.

    4. Re:Learning functional programming by rjh · · Score: 2

      Yes, I'm sure it's better than (especially) C and C++, but nothing compares to the module system of SML.

      This may be the source of some of our disagreement; you're an academic, and I'm in the trenches. :) I can't talk intelligently about SML, seeing as how I've never used it (although if you could point me towards a compiler and a good learning reference, I'd like to look at it). What I can talk intelligently about is how utterly miserable C is for large-scale software projects.

      Given that most large-scale software projects now are written in C, or a similarly low-level language, I consider pretty much any sane language choice that moves us to a higher level of abstraction to be a Good Thing. Whether we use LISP, Scheme, Python, C++, Java--I don't care all that much, really, as long as it's a step up from C.

      So from my perspective, Python is a brilliant choice for software development. Manna from heaven, even. :) But I do acknowledge that there are probably more elegant and clean languages than Python.

      I dunno what parentheses have to do with elegance, but I can tell you that LISP is not "as good as it gets" as far as elegant functional languages go.

      Actually, I was using LISP as an example of a functional language in which the syntax of the language (the Lots of Idiotic Stupid Parenthesis) wind up to some degree hobbling the utility of the language. Once I get a function working in LISP, the first thing I do is go through it and remove as many parenthesis as I can in the hopes of improving readability and maintainability.

  30. Re:CS Vs SE by CharlieG · · Score: 2

    The problem is that most univerities out there still only have a CS program, not a SE program. I've been ranting on this topic for at least a dozen years or so.

    The head of the CS department of my old college is a friend of my Father-in-law, and they don't see the problem - which is why they keep producing people with CS degress, and they can't work in the real world

    --
    -- 73 de KG2V For the Children - RKBA! "You are what you do when it counts" - the Masso
  31. Secure by default by ahde · · Score: 2

    Not to flame, but

    "Four years without a remote hole in the default install!"

    is nothing compared to MS-DOS's twenty year safety track record. That, and thousands of "potential" buffer overflows in realistically safe code like this:

    int SomeFunc ()
    {
    char foo[5] = "Hello";
    OtherFunc(foo);
    }

    OtherFunc(char * foo)
    {
    /* this is only ever called from SomeFunc(),
    * whic passes a string literal. This is, of
    * course, completely undocumented. You never
    * read this comment.
    */

    char * bar = malloc(strlen(foo)+1);
    strcpy(bar, foo);
    }

    Yes, OpenBSD is a very nice OS, but no, it isn't a magic bullet.

  32. Re:Poor old strcpy by Chris+Burke · · Score: 2

    It -is- relevant that it is used inappropriately. That it is so easy to do is exactly the problem. Scissors are a bad example. Try the Chevy Corvair. Sure, if you were really carefull it wouldn't blow up... The problem is just how careful you had to be.

    Like any computer operation, strcpy() is safe given a certain set of invariants. In this case, the invariants are that both src and dest are non-null buffers, and that the src is of at most equal size to the destination buffer. However, the only way to know this is to know the size of the src (either at compile time, or strlen()), and the size of the dest.

    But since you already have to know the size of the dest, why not just include that as a parameter to the copy? You've eliminated the problematic invariant, and replaced it instead with the invariant that the length parameter you pass has to be correct. Since you have to know that anyway, this should clearly be better.

    The only time strcpy() ever made sense was on machines so small that it was advantageous to -not- have to check the size. As soon as this was no longer the case (which i'd argue was as early as the C64), strcpy() should have become deprecated in favor of strncpy().

    --

    The enemies of Democracy are
  33. Re:Exceptions are exceptional by ahde · · Score: 2

    Not with java. Exceptions are a normal part of program flow. Not of necessity, but enough of the standard APIs and documentation relies on them to make it fairly standard.

  34. Re:Exceptions are exceptional by slamb · · Score: 2
    I said: Remember, exceptions are exceptional - if you are throwing them regularly, something is wrong. The only one I have that's thrown even remotely close to commonly is IOBlockError - basically EWOULDBLK/EAGAIN in exception form.

    ahde said: Not with java. Exceptions are a normal part of program flow. Not of necessity, but enough of the standard APIs and documentation relies on them to make it fairly standard.

    I don't buy that. Yes, just about any function that can signal an error condition does so by an exception. But if your code is correct, that will not happen many times in an execution. I.e., if you've got an inner loop that throws/catches an exception at every iteration, you're doing something wrong. Exceptions are, by definition, not regular program flow.

  35. Re:Why is this code bad? by ahde · · Score: 2

    you need to do:

    char dest[MAXLEN];
    if (strlen(input) >= MAXLEN -1) /* strlen() does not count the terminating null */
    {
    /* handle error */

    /* you have to check this before doing your use strcpy() -- or else the damage will already be done */
    }
    else
    {
    strcpy (dest,input);
    }

    this still leaves two possible errors, if
    input is less than or equal to MAXLEN but
    not guaranteed to have a terminating null
    character. You will either lose a character, or end up with an unbounded string.

    you need an additional condition:

    else if (strlen(input) == MAXLEN -1)
    {
    /* check for null byte at last place */

    if (input[MAXLEN] == '\0')
    {
    /*ok */
    }
    else
    {
    /* optionally add it, or handle error */
    }
    }

    or else, do the same as strncpy and call bzero() or memset() to fill the whole dest[] array with zero bits before copying. This is a little more expensive.

  36. Garbage collection and the Heap by Tom7 · · Score: 2

    Actually, in a long-running system (such as a network server), a garbage collector is an advantage, not a liability:

    1. Memory leaks are not possible.
    2. Heap compaction IS possible (the garbage collector can move around data rather like DOS defrag). That means that the heap loses its fragmented nature when necessary. It's true that a C program does less allocation, but the malloc model doesn't allow for the heap to be defragmented! So for a long running program, you are typically stuck with fragmented memory that can't be reused...

    So I say garbage collected languages win on this point!

  37. Re:Why is this code bad? by CoolVibe · · Score: 2
    Even easier:

    strlcpy(dest, input, MAXSIZE);

    or:

    strncpy(dest, input, MAXSIZE);
    dest[MAXSIZE - 1] = 0x00;

    No need to go to all that trouble.

  38. Re:Poor old strcpy by Chris+Burke · · Score: 2

    Bah, if your string is not null terminated, you are introducing a bug. Neither strcpy nor strncpy ensure this, so it is still left to the programmer to do it. If it is done to the source string (and as you said, you know the destination size) before it is ever feed to either function, which one you use is irrelevant.

    If you force a null in your source at a location determined by the size of the destination prior to copying, then you've effectively changed the semantics of copying strings, which normally leave the source unchanged. Copying long strings into various smaller-sized buffers would have different behavior depending on the order in which you did the copying.

    Forcing null-termination of sources is not the answer, because if you have a source that is not already null-terminated, then you have a bug elsewhere in your code. We're talking about strcpy()-related bugs here. That means you already have a string in a buffer of sufficient size to hold the string.

    So by fixing the bug in the program (by ensuring all strings are null terminated, not by replacing every strcpy call with strncpy) you are also ensuring the program is secure (it is no longer vunerable to buffer overflows), wasn't that one of the points of the original article?

    No, because the problem isn't strings that aren't null-terminated. The problem is strings that are too big for the space they are going to go in. It might seem like these are the same thing, but they aren't.

    This doesn't mean strncpy is useless, for example, you may have to use a string you don't want to (or can't) vary by null terminating it (a constant perhaps), so you'll need strncpy to safely make a copy of it that you can play with.

    Having a copy to play with is why strcpy() is used. If it was acceptable to modify the source, then you wouldn't make a copy.

    --

    The enemies of Democracy are
  39. Re:Poor old strcpy by Chris+Burke · · Score: 2

    The bug being that you didn't ensure the termination...

    No, the bug is that your input reading routines are unsafe. But regardless, the point is to fix that bug at the source, not fix it every time you're about to call strcpy().

    Making assumptions about the input is the strcpy bug isn't it?

    No, that would be a gets() or scanf() bug, in most cases (which, btw, are worse than strcpy()). The strcpy() bug is copying a string too big for the dest buffer, and that doesn't have to have anything to do with input. Not to mention that ensuring that your very large input is null-terminated doesn't stop you from having a buffer overflow when you strcpy() that string into a smaller buffer. I told you they weren't the same thing, but you didn't believe me. :)

    Well you may want to store a copy of a string, the contents of which changes, there are plenty of reasons for duplicating a string, modification is only one of them.

    If your intent is to copy source so you can change it later, well that's not really any different. In fact there is very little reason to make a copy of a string unless you intend to (or intend to allow) changes to one or the other that you don't want reflected in both. The only exception would be copying into a specific buffer for something like an RPC call. In any case, strcpy() is unsafe unless you modify the source, which as I said changes the semantics of copy.

    BTW, most of those cases where you are making a copy of a string whose contents change -- such as getenv() or other functions that return a string pointer -- are bad because they aren't thread safe. :)

    I just feel strcpy is offered as a scapegoat, for the causes of insecure programs (when I'm sure we both know it is poor programming practices). So I stand by original statement, strcpy does what it claims to do, if you use it to something when you actually wanted to do something else, more fool you. Forcing people to use strncpy instead of strcpy will not ensure safer programs.

    If you think I'm saying not using strcpy() will make all programs secure, then you've misread everything I've said. With that understanding, realize that I'm saying strcpy() is a poor programming practice. It "claims" to do something that is fundamentally unsafe to do without even the basic check of having a length field.

    --

    The enemies of Democracy are
  40. Re:Poor old strcpy by Chris+Burke · · Score: 2

    So if I assume that my source string will fit into my destination string, this is not making an assumption on the input to the function? It seems the same to me. :)

    Oh...Input to the function, in this case strcpy(). I was talking about input to the program. Input you read from a file (which includes stdin, of course) can be of any length, and assuming otherwise is a common error.

    It doesn't however enforce that you can't check the field length before hand, the same way there is nothing stopping you from checking the value of a pointer before you try to dereference it.

    And what do you do if the dest field is too small? You can't use strcpy() anymore. You either 1) modify the src to make it smaller (bad, modifies copy semantics), 2) exit on a failed assert() (bad, makes a condition unecessarily fatal) 3) use an alternate code path in this case (hacky, ugly, and would probably just be a call to strncpy()) 4) just use strncpy() in the first place.

    Note that I'm assuming that if you are using a dynamically allocated buffer, you would just be checking the size and (re-)allocating a big enough buffer in the first place. That isn't a general solution, so I don't include it.

    If I've already verified my assumption that the source string is smaller then the destination string (validating the input), I can safely use strcpy(). I could just as easily use strncpy(), and then check that the destination string is null-terminated (validating the output). Both of these methods still require validation, so I don't see the gain in using one over the other. Without validation, strncpy() is safer, the same way it is safer to be in a car with airbags then a car without if you never wear a seatbelt.

    What do you mean, "verified my assumption that the source string is smaller than the destination string"? Look, if you had that assumption, then you should have stated it. Because that's not an assumption I'm making, nor requiring. It is a bug to use strcpy() when the dest is smaller than the source. You are getting around the bug by assuming that the dest is big enough, and checking that assumption. So above where you talk about making an assumption about input... That's an assumption you're making, not some theoretical bad programmer. Well, no wonder you don't see the gain.

    The way to understand what you gain is to realize that there are two prerequisits for the bug: 1) use strcpy() 2) src bigger than dest. You try to eliminate the second condition by assuming it is true and checking (with unspecified error recovery), not realizing that all you need to do is eliminate the first condition! You've added an unecessary invariant to every string copying operation. An invariant, I might add, that it isn't all that uncommon to have be untrue, which is the worst kind of invariant to have. The reason why strncpy() is better is because it doesn't require this invariant.

    strncpy( dest, src, dest_size); dest[dest_size-1] = '\0'; always works, no matter the size of dest and src, and without modifying the src, calling exit(), or any other such sloppiness. Well, obviously, dest and src can't be NULL and whatnot, but those certainly aren't caveats specific to string copying operations.

    I hope it is clear why code that always works with minimal assumptions is better than code that only works with additional bad assumptions and an unclear and almost certainly undesireable recovery path should the assumption prove false. I hope it is clear why strncpy() is the former, and strcpy() the latter.

    All that being said, I do wish that strncpy() would stick the null in itself. It only saves a line of code, but it's a line of code you always need and thus it only makes sense to roll it into the function you need it with. I usually end up making an inline function that just does exactly that. Actually, I just wish more systems supported the OpenBSD strlcpy(). :P

    --

    The enemies of Democracy are
  41. Re:Poor old strcpy by Chris+Burke · · Score: 2

    Not only is it an assumption I'm making, but (as I stated) also an assumption I'm verifying in the hope that I don't get mistaken for that theoritcal bad programmer.

    But you haven't indicated what happens when that assumption proves false. What do you do? No offense, but making this assumption when unecessary I think constitutes bad programming.

    What happens when you want everything that is in src, not just what fits in dest? I guess that would be another unstated assumption.

    That's not an assumption (that you want everything in src to be copied into the dest), that's a goal. You're then dealing with a special case of copying. But, taking that as a goal (which may be common, but is not an aspect of general string copying), you're in either 1 of 2 cases:

    1) You can do dynamic (re-)allocation, because you have control over the dest buffer. If you absolutely have to have the entire string fit in the src, this had better be the case. I already addressed this case, last post.

    2) You can't dynamically create the source at that point (the function in which you are doing the copying did not create the buffer, and can't re-allocate it). In this case, well, you've pretty well painted yourself in a corner by requiring something you can't control. What do you do?

    Bottom line for this: If you need that extra constraint on operation, then you must provide it. Regardless, my 2 lines of code will always be safe, with the minimal amount of constraints.

    Of course this gets messy because you then make the assumption that src has a reasonable finite size.

    Finite is a good assumption. Reasonable is not. If you are requiring that you can copy the whole src into the dest, then you allocate your buffer right there and let malloc() decide if it is "reasonable".

    I worry something like this will appear: "*Note: We use strlcpy() here because it is safer then strcpy() and strncpy().", forgetting of course to add the checks.

    No doubt. Shitty books abound; no need to wait for them to be written. Yet here's something curious: strncpy() without the check is still more secure than strcpy(). So long as your dest size is always correct, then even if you have non-null terminated strings floating around, you'll never write more than the target buffer can hold. Thus you won't have buffer overflow. Though you'll probably segfault first time you call strlen() or printf() :)

    In the end I feel that the copying of strings is not a trivial exercise in C, and if people don't validate (ie check) their assumptions (or even realise they are making them), then trouble will ensue, not matter what standard function they use.

    That is true, but also meaningless. It's the same as the "all OSs have had security issues, so you can't compare security" argument. C does require care, but that doesn't mean there aren't good and bad functions, or good and bad assumptions/invariants. Part of being careful is picking the right tools. "C was not designed to be safe" isn't an excuse to go sprinkling your code with set/longjump() or gets(). And it doesn't get around the fact that strncpy() is preferable to strcpy() in nearly every way.

    Though you keep talking about "checking" assumptions. Note: dest[dest_size-1] = '\0' isn't a check, it's a guarantee. It doesn't check if the assumption holds true (so you can take corrective action), it causes the assumption to hold true. That is good code, and a good assumption.

    Also, there is nothing stopping people from creating their own wrappers (as you suggested with your inline function), this could be done once (for a program, or a project, or all projects), and it is never a concern again.

    Show me the version of the inline function that uses strcpy(). I can't come up with one that is both safe and free of undesireable behavior off the top of my head, but then again I'm not spending much effort because I already have a strncpy() version in 2 lines.

    --

    The enemies of Democracy are
  42. Re:Why is this code bad? by ahde · · Score: 2

    he was asking about his code. strlcpy and strncpy will both get the job done (if available) but I didn't think that was what he was asking. Besides, you could clean up my code, put it in a library and call strahdecpy() just as easily.