Secure Development Rule #2: Check Status Returns
The two-week buffer overflow exercise just described allowed the developers and managers to examine their software and make another discovery. Throughout the code, developers found that the returns from a number of functions and system calls were not checked. In addition, one of the programmers found that a function not only had potential buffer overflow problems, but the failure to check the return from system calls may be the cause of a longstanding bug in their software that caused database connections to fail if the user was not logged in as the administrator. The workaround for the bug was to log in as the administrator before executing this function. Security managers and database administrators did not like this requirement, but allowed it for the sake of production. The programmer who did the analysis reprogrammed the function to check status returns and add proper error handling. When finished, the three-year old bug was no longer a problem.
In this case, the problem was writing to an open network connection where the database was on the local machine. According to many programmers, it is one of those "this cannot fail" system calls. In fact, by checking the return codes it was discovered that failure conditions could arise that included operating system bugs. Mike changed his company's software development policy to say that all system and function calls must be checked for success or failure, and then he ordered the programmers to go through the software and check the return from every system call and function call.
Before you ask, this company told its customers that they were delaying their next promised major release of the software. Instead, they promised significant bug fixes to the existing software. Many of the customers were happy to wait and see what was delivered. With that, Mike set aside four weeks to allow the programmers to go through the software and fix these problems.
Not everything went as planned. Six weeks later, these programmers had fixed hundreds of cases where system calls and functions were not checked. They added many lines of code for new error-handling functions. In the end, they fixed dozens of outstanding bugs and closed many security holes, including the removal of several backdoors left by previous employees. They also removed all of the requirements for programs to be run as privileged users.