A Bug Hunter’s Diary is written as a journal of a “Bug Hunter”. It takes us through seven bugs that the author (Tobias Klein) has discovered in the past five years, giving the reader a glimpse of his process and an awareness of how easily bugs can creep into even the most carefully written software.
All of the bugs discussed in this book are related to memory errors that lead to a proofs of exploit that involve overwriting the program counter (and thus hijack subsequent program execution with arbitrary code). This narrow focus sets the stage for a book that is very heavy on Assembly code, debuggers, and a few easily compromisable C functions.
Some of the bugs involve open source software so we have source code to step through, but others provide nothing more than the finished binary to step through with a debugger and a disassembly of the machine code. For someone who doesn’t do much C programming anymore and hasn’t done Assembly in over 10 years, such as myself, the journey can be quite daunting. The guide on this journey stops occasionally to explain his intuition for certain decisions, but we’re largely left to just follow him along without really knowing how he knew to check for certain things and not others. After following him on 7 missions, however, some patterns do become evident. This repetition enables the reader to feel like more of a partner in the later journeys to contrast his bystander role in the first few.
If you can think of my train of thought during the reading of this book as a process, then this process had a few different threads running in parallel. In one thread, I was just trying to follow the Bug Hunter and understand the lessons as they were presented. In another thread I was trying to identify analogs in these lessons to my own domain of programming (e.g. web programming, and database programming). There were also a thread that was periodically assessing the author’s style and the the book’s relevance, to various target audiences, and its importance to software.
Thread 1: Just trying to keep up
If I had read this book as a tutorial where I actually do as the author says, it would have taken me a lot longer to read. At a certain point I just settled for getting the gist of what he was doing and focused more mental cycles to Thread 2.
Thread 2: Applying the Lessons to My Domain
The process that Klein uses to track down bugs serves as a forceful reminder of how bugs could slip into my own software if I’m not careful. In trying to exploit memory errors, Klein would focus on the interfaces between user space and kernel space as logically any exploit must pass through one of these bridges at some point. There is an analog in any programming environment. In web development you are looking for the entry points where user input is passed to the application. This book is a reminder that you must always be conscious of where data could possibly have come from before working with it as it is often a combination of small glitches that result in a large exploit down the road.
Thread 3: The Author’s Style
Klein writes much of this book as a sort of diary of his actions. As such it is more like a day in the life of a bug hunter than it is a tutorial on how to become a bug hunter. This style works well for imparting an authentic view of what a bug hunter really does – and as such might serve as inspiration for those who want to follow this craft.
At times (more early on than later) I struggled to grapple with the direction Klein was taking us. Is he just reciting his exploits as a way of bragging, or is he recounting his steps and building up to an eventual purpose. Throughout the second and third bugs I was bogged down a little with thoughts like “this is way too dense in Assembly for the average person”, but these would be countered with rebuttle thoughts like “but this isn’t intended for the average person…”. As I settled in, though, these thoughts were replaced by less critical internal commentary like “wow, it would be really easy to make that mistake” or “that’s really neat!”
By the time I reached the sixth and seventh bugs and I had seen the same types of bugs appear over and over, I had become a true believer. Not only was this book interesting; It was essential! Despite the lip service that is paid to “good programming practice” in computing science programs, I have never been made so acutely aware of some of the simple programming mistakes that can result in dreadful consequences. As I finished the seventh bug, the one clear capstone thought was that this book should be required reading to anyone who wants to write any software. Just as engineers are required to take an ethics course, computer scientists should be required to take a “Bug Hunters” course – if for no other reason than to raise their awareness of the nature of bugs.
When I think about the “buggy” code that I have read from new University grads it makes me shiver. Much of this buggy code is in production around the world and quite often the develop has no idea that the bugs are there. This book highlights a few specific functions to handle with great care in C, but every language has its own set of traps that all new programmers fall into. (E.g. in PHP registering global variables, unvalidated input to SQL queries leading to SQL injection, etc…). Computer books very rarely spend much time highlighting these traps, and as a result young programmers regularly fall into them. Unfortunately with software these traps often don’t give immediate feedback. Instead they linger for years before they are exploited – and sometimes to great disaster.
I meandered a bit in this review, but to summarize. If you can slog through the dense debugger readouts and assembly code and latch onto the core message in this book you will become a better software developer. Even if you don’t learn anything new in this book, it will serve to raise your awareness and prevent a bug.
And one more thing: This book should be required reading for new software developers.