Supplemental files and examples for this book can be found at http://examples.oreilly.com/9780596003944/. Please use a standard desktop web browser to access these files, as they may not be accessible from all ereader devices.
All code files or examples referenced in the book will be available online. For physical books that ship with an accompanying disc, whenever possible, weve posted all CD/DVD content. Note that while we provide as much of the media content as we are able via free download, we are sometimes limited by licensing restrictions. Please direct any questions or concerns to .
Foreword
There is a humorous, computing-related aphorism that goes like this:"There are 10 types of people: those who understandbinary, and those who don't."Besides being amusing to people who understand number representation,this saying can be used to group people into four (or 100)categories:
Those who will never quite get the meaning of the statement, even ifit is explained to them
Those who need some explanation, but will eventually get the meaning
Those who have the background to grasp the meaning when they read it
Those who have the knowledge and understanding to not only see thestatement as obvious, but be able to come up with it independently ontheir own
There are parallels for these four categories in many different areasof endeavor. You can apply it to art, to cooking, toarchitecture...or to writing software. I have been teaching aspectsof software engineering and security for over 20 years, and I haveseen it up close. When it comes to writing reliable software, thereare four kinds of programmers:
Those who are constantly writing buggy code, no matter what
Those who can write reasonable code, given coaching and examples
Those who write good code most of the time, but whodon't fully realize their limitations
Those who really understand the language, the machine architecture,software engineering, and the application area, and who can writetextbook code on a regular basis
The gap between the third category and the fourth may not seem likemuch to some readers, but there are far fewer people in that lastcategory than you might think. It's also the casethat there are lots of people in the third category who would claimthey are in the fourth, but really aren't...similarto the 70% of all licensed drivers who say they are in the top 50% ofsafe drivers. Being an objective judge of one's ownabilities is not always possible.
What compounds the problem for us all is that programmers areespecially unlikely to realize (or are unwilling to admit) theirlimits. There are levels and degrees of complexity when working withcomputers and software that few people completely understand.However, programmers generally hold a world view that they can writecorrect code all the time, and only occasionally do mistakes occur,when in reality mistakes are commonplace in nearlyeveryone's code. As with the four categories, or thedrivers, or any other domain where skill and training are required,the experts with real ability are fewer in number than those who believe they are expert. The result is softwarethat may be subtlyor catastrophicallyincorrect.
A program with serious flaws may compile properly, and work withobvious inputs. This helps reinforce the view that the code iscorrect. If something later exposes a flaw, many programmers will saythat a "bug" somehow"got into the code." Or maybe"it's a computerproblem." Neither is candid. Instead, whoeverdesigned and built the system made mistakes. As a profession, we areunwilling to take responsibility when we code things incorrectly. Isit any wonder that a recent NIST study estimated that industry in theUnited States alone is spending $60 billion a year patching andcustomizing badly-written software? Is it a surprise that there arethousands of security patches per year for common software platforms?We've seen estimates that go as high as $1.5trillion in damages per year worldwide for security problems alone,and simple crashes and errors may be more than 10 times as much.These are not rare flaws causing problems. There is a real crisis inproducing quality software.
The reality is that if we truly face up to the situation, we mightreassess some conventional beliefs. For instance, it is not true thata system is more secure because we can patch the source code when aflaw is discovered. A system is secure or it is notthere is no"more secure." Youcan't say a car is safer because you can replace thefenders yourself after the brakes give out and it goes over a cliff,either. A system is secure if there are no flaws that lead to a violation of policy. Being able to installthe latest patch to the latest bad code doesn't makea system safer. If anything, after we've done it afew times, it should perhaps reduce our confidence in the quality ofthe software.
An honest view of programming might also cause us to pay moreattention to designto capturing requirements and developingspecifications. Too often we end up with code that is put togetherwithout understanding the needsand the pitfallsof theenvironment where it will be used. The result is software thatmisbehaves when someone runs it in a different environment, or withunexpected input. There's a saying that has beenattributed to Brian Kernighan, but which appears to have first beenwritten down by W. D. Young, W.E. Boebert, and R.Y. Kain in 1985:"A program that has not been specified cannot beincorrect; it can only be surprising." Most of thesecurity patches issued today are issued to eliminate surprisesbecause there are no specifications for the underlying code. As aprofession, we write too much surprising code.
I could go on, but I hope my points are clear: there are some realproblems in the way software is being produced, and those problemslead to some seriousand expensiveproblems. However,problem-free software and absolute security are almost always beyondour reach in any significant software project, so the next best thingis to identify and reduce the risks. Proven approaches to reducethese risks include using established methods of softwareengineering, exercising care in design and development, reusingproven software, and thinking about how to handle potential errors.This is the process of assuranceof building trust in oursystems. Assurance needs to be built in rather than asserted afterthe software is finished.
That's why this book is so valuable. It can helppeople write correct, robust software the first time and avoid manyof the surprises. The material in this book can help you provide anetwork connection with end-to-end security, as well as help youeliminate the need to patch the code because youdidn't add enough entropy to key generation, or youfailed to change the UID/GID values in the correct order. Using thiscode you can get the environment set correctly, the signals checked,and the file descriptors the way you need them. And along the way,you can read a clear, cogent description about what needs to be setand why in each case. Add in some good design and careful testing,and a lot of the surprises go away.
Are all the snippets of code in this book correct? Well, correct forwhat? There are many other things that go into writing reliable code,and they depend on the context. The code in this book will only getyou partway to your goal of good code. As with any cookbook, you mayneed to adjust the portions or add a little extra seasoning to matchyour overall menu. But before you do that, be sure you understand theimplications! The authors of this book have tried to anticipate mostof the circumstances where you would use their code, and theirinstructions can help you avoid the most obvious problems (and manysubtle ones). However, you also need to build the rest of the codeproperly, and run it on a well-administered system. (For that, youmight want to check out some of the other O'Reillybooks, such as