Thursday, July 5, 2007

Oops, the RegExp was too greedy.. and no one thought about cancel. The race is on!

I have a saying. Don't write bugs, your program has enough with the ones you don't know about. What I mean by this is don't write code that you know can fail under certain rare circumstances/inputs/races because murphy's law says those circumstances will occur. Also, since you're not perfect, those special case might be more common than you think and may interact with bugs you don't know about to create little disasters.

Recently I changed my CVS password on our local CVS server. This was done by using a very convenient script. My login name is "at". When I changed my password "mat"'s account was deleted. Later, a colleague "vsingh" went on the server to check to see if his account was deleted and all the user accounts except his disappeared. What happened?

Well, the convenient script changed the passwords by reading in the whole file, deleting all the lines that contained "username:" and witting out the file again appending the new password. It's unfortunate that the script's RegEx didn't bother to match newlines as it meant that when "at" changed his password "mat"'s account was deleted. Good thing "pat" and "arafat" don't work in R&D..

So, why did user "vsingh" delete everyone's account? Well, user "vsingh" was only interested in whether his account was deleted, so he got far enough to type in a password then typed ctrl-c to cancel. Unfortunately the script behaved badly when it was canceled. Instead of reading in the file, modifying it then writing it out it canceled reading the file, added vsingh and over-wrote the original. Net result: some panic until we restored the file from backup.

Oh, and there's still a race condition in the script too. Can you spot it? Thankfully that hasn't manifested yet.

No comments: