我这个blog架在Azure中的一台Linux虚拟机上,还开启了SSL。本来一个个人blog,访问量几乎没有,完全用不着SSL的,只不过是因为我手上恰好有一张能用的证书,放着也是浪费,于是就拿来用到这个blog上了。于是,就赶上了前几天那个闹得很凶的heartbleed bug。
这个bug对我的blog当然没什么影响,除了收到了一堆提示邮件,有Azure的,有证书签发商的等等。给Linux打补丁之余,这倒是让我有机会关注了一下这个heartbleed bug的来龙去脉。原来,这是个忘记检查内存访问范围的bug。两年前,有人向OpenSSL提交了一段代码,其中在分配内存空间时,写程序的忘记检查内存范围了。糟糕的是,用来申请内存空间的参数是由用户指定的,这就使得用户有机会拿到比需要的内存大的空间,以及其中的信息,这就造成了信息的泄露。
这个bug让我想到了另一件事。许多年前,我还年轻的时候,和很多现在的年轻人一样,喜欢和人争论。那时候软件行业的争论焦点之一是,到底开源更好,还是闭源更好。那时候,Eric Raymond的文章《大教堂和集市》很流行,拥护开源的人相信,用小集市的方法,聚集更多的人,能够建出更好的大教堂。具体到代码上,他们相信开源代码有更多的人做code review和测试,bug会更少,质量会更高。可是这个heartbleed bug却好像是对这一理论的嘲讽。Azure很骄傲地给我发信说,Azure的基础设施没用OpenSSL,用的是微软自己的Secure Channel,所以不存在这个bug,我只需要给自己用到OpenSSL的应用打补丁就行了。而更多的网站是发邮件说,他们被这个bug影响了,但相信没有用户资料损失,但还是建议改密码。按理说,OpenSSL的使用者比Secure Channel的多得多,可是为什么这个bug躺在那里两年也没人发现呢?
我的看法是,由于软件复杂度的增加,现在基本上靠code review来找bug基本上已经越来越难了。大型软件除错只能靠大量的测试,测试越完备,bug可能越少。而开源社区基本上很少有专门的测试人员,大家乐于贡献代码,但是没人只想贡献test case。另外一点是,人力资源是很贵的。就这个heartbleed bug来说,可能即使有专门的测试人员,它也很难被test case覆盖,原因是要找出这个bug,需要对SSL,特别是SSL heartbeat非常了解。对这么冷门的东西非常了解的人,基本上会是这个领域的专家了。而你知道,专家是很忙的,哪有时间review到这么细节的code,而且又不是为了赚钱。至于其他人,这段code能拿来用对,就算不错了,哪里有能力review出其中的bug啊。