In this first installment in a series of excerpts from ‘Practical Unix & Internet Security‘, 3rd Edition, you’ll find tips and general design principles to code by that will help you avoid security-related bugs.
In this first installment in a series of excerpts from ‘Practical Unix & Internet Security‘, 3rd Edition, you’ll find tips and general design principles to code by that will help you avoid security-related bugs.
This first installment seem to be simple things that every programmer should always do, but for some reason does not. Just following the rules of this first installment would kill 70% of the virus code that run in Windows today. And I understand that a large percentage of Linux programs will break or crash in odd ways if you feed them random garbage as thier arguements because they don’t follow the procedures(sp?) given here.
The part about testing the return values of system calls is a must. I did this for every system call I made in a BeOS program only the find that the returned values did not match what I expected from reading the BeBook. If I had not seen it early in development of the code the diffirence in values would have made a almost untraceable if I first wrote 90% of the code and then tried to jazz it up using the system calls returned values.
In particular, the articles Call0 and Call1 macros are BAD, as it asks that you do required work within an “assert” statement. The example expands to:
assert ((fd = open (“foo”, O_RDWR, 0666)) != 0)
Normally this would be fine. However, if you define the NDEBUG pre-processor symbol, then the assert statement is removed by the pre-processor, leaving you with NOTHING.
This is a fast way to introduce hard-to-diagnose bugs in your code, as it will work properly under a DEBUG build, but will fail under a “release” build.
A good rule of thumb is to never execute side-effect generating code within an “assert” macro.