Archives

环海南岛骑行计划

本来计划今年不出去的,等到春节放假的时候再去海南。结果这两天看到春节去海南的机票价格猛涨,比我前几天看的时候翻了一倍还多,心里拔凉拔凉的啊!

好在我机灵,春节去不成那就元旦去,元旦时候还是有很便宜的机票。但是还有个问题,明年的放假安排还没出来!不管了,反正春节会有一周的假,管你们什么时候放,我先提前用了再说。于是我马上给米国的经理发邮件说预支春节的假期,经过商议,最后我们一致认为可以把春节的假期调到米国圣诞节长假的时候(不少老外是圣诞节之后休年假一直休到元旦)。

这样我就凑出9天时间了,其中从春节长假中调来了4天,从元旦转来了1天,没有用自己的年假。如此一来,出发时间比预计更提前了,25号就要出发了。我觉得我可能是我们公司最会擅长调休的人了,每次出远门基本上都是用眼花缭乱的调休,让同事们目不暇接啊。

买机票时也有学问,如果从北京飞,仍然不便宜,所以改从石家庄飞。而且飞海口比飞三亚还要贵一些,所以改飞三亚。最后,从石家庄往返三亚的机票900¥就搞定了,加上从石家庄往返北京的动车票也就1060¥。要知道春节从北京飞的机票的话,单程就已经是1800¥了,也就是说我这么一调整省了2600¥!

但是,便宜也有便宜的坏处,那就是去的航班是中午到、回来的航班是中午起飞,也就是说有一天基本上都浪费了。网上的攻略写的都是9天,所以我还必须补上一天,一来骑完可以休息一下,二来以防万一。再调休一天不是不可能,只是我觉得那样就太过分啦,忍痛割爱请一天年假好了!最终定为24号出发,2号返回北京,3号上班。

因为网上环海南岛的攻略都是从海口出发回海口,我必须调整为从三亚出发回三亚,经过修改后的行程就成了:

12月24号,Day 1:三亚——天涯——崖城——黄流——板桥 (约为137公里)
12月25号,Day 2:板桥——东方——太坡——昌江 (89公里)
12月26号,Day 3:昌江——雅星——儋州 (79公里)
12月27号,Day 4:儋州——福山——海口 (130公里)
12月28号,Day 5:海口——灵山——三江——大致坡——潭牛——文昌——清澜镇 (117公里)
12月29号,Day 6:清澜——迈号——会文——长坡——琼海——博鳌 (85公里)
12月30号,Day 7:博鳌——龙滚——万宁——兴隆温泉 (93公里)
12月31号,Day 8:兴隆——陵水——英州——亚龙湾 (120公里)
1月1号,Day 9:亚龙湾——三亚 (约为30公里)
1月2号,Day 10:返回石家庄,返回北京

仍然是顺时针方向环岛,只是起点变成了三亚。

上面的安排有个问题,就是如果第1天到三亚就开始从机场骑的话,飞机到达就已经是上午11点多,就算组装车子顺利的话也要12点多才能出发,以我这种速度137公里最快最快也要骑6个多小时,而现在的天黑时间大约是5点多,这就意味着天黑之后还要骑一个小时。而第9天30公里也就骑不到2个小时,很不平衡。

解决方案有二:一是,第1天少骑一些,中途住宿,在第2天时补回来,这样就不会影响后面的进度,但是不知道第1天的路上还有哪些住宿地方;二是,到达之后第1天休息,第2天开始骑,这样上面的骑车行程全部延后一天,可是最后一天要从亚龙湾赶到三亚机场坐12点20的飞机,时间上感觉很紧张,不过理论上其实也够了。

我比较倾向于第一种方案,我可不想把后面的时间搞得太紧张以至于误了飞机。而且一路上似乎也并不都是有住宿的地方,所以扎营的装备似乎也得自己带,因此第1天骑到哪里并不那么重要了。

而剩下的问题就是怎么拆自行车以及怎么带那些装备了。考虑到海南的气候,防雨应该是必须的,所以一些雨具还是要准备。而我那辆山地车的配件还没买齐,缺一个后座,两个挡泥板,一个驼包,一个车灯。还有三个星期的时间,准备时间足够了。

从上面你也可以大体看出,我每次出远门都是怎么计划和准备的了。尤其这是第一次出门骑自己的车子,更要慎重。所以说,长途旅行计划和安排行程可能并没有你想象的那么简单,各种因素必须考虑周全。

无论如何,我正在一点儿一点儿地实现着自己的梦想!虽然离我环游世界的梦想还差很远,但我从未放弃。:-) 此刻,我正憧憬着一个人骑着单车行驶在海南岛公路上的情景:吹着徐徐而来的清凉的海风,一边是树木一边是海滩,前方是那一望无际的碧蓝的大海,而我留下的只有骑着单车驮着行李的背影……这一天很快就要到来了……

这世上最美的事莫过于看着自己的愿望一点儿一点儿变成现实!加油!

(P.S. 环海南岛期间将通过我的饭否即时更新每一天的见闻:http://fanfou.com/wangcong。但愿海南岛一路都有手机信号!)

和仓央嘉措有关的诗歌

你或许没听说过仓央嘉措,但你很可能听过“那一生,那一世”。他是六世达赖喇嘛,在很多人心目中他是一个不折不扣的“花和尚”。

历史上像仓央嘉措这样神秘而且被严重误读的大人物恐怕不多(当然不能算那些被某些人刻意篡改的),主要是因为正史中关于他的记载实在是太少,以至于关于他更多的是民间的传说。而他的诗歌在被后人翻译的过程中又各种被曲解,久而久之,他就成了今天人们心目中“流浪在拉萨街头”的“世间最美的情郎”,而他的诗歌也被流传为朗朗上口的情歌,折杀了无数少女的心……

这本书就是从历史的角度来试图还原出一个真实的仓央嘉措。无奈传说多过史说,书中很大篇幅都是在辟谣,最后作者自己推出的结论也只是自己的一个比较靠谱的观点而已,史实是不是这样我们谁也不知道。建议每一个想了解仓央嘉措的人都应该读一下这本书,起码你会知道,真实的他并不是一个花和尚,那些情诗要么是被错误翻译和演绎,要么是被“张冠李戴”地加到他头上去的。用妹子的话说是,“有些事看似风月,其实无关风月”!

其中最出名的当属那首“那一生,那一世”:

那一天,闭目在经殿香雾中,蓦然听见你诵经的真言
那一月,我摇动所有的经筒,不为超度,只为触摸你的指尖
那一年,磕长头匍匐在地,不为觐见,只为贴着你的温暖
那一世,转山转水转佛塔,不为修来生,只为途中与你相见
这首情诗实际上不是仓央嘉措写的,它是出自《信徒》这首歌。

那首“东山诗”,即“在那东山顶上,升起皎洁的月亮,年轻姑娘的面容,浮现在我的心上”,确实是仓央嘉措写的,但被译者误读,后人在这个错误的基础上又进行了加工。原诗中对应“年轻姑娘”的是“未生娘”这个奇怪的词,不见得就是情人的意思。

那首 “日夜爱恋的情人,如能成为终身伴侣,哪怕是海底珍宝,我也把它捞上来”,无法确定到底是不是出自仓央嘉措。

还有那首《见与不见》:

第一最好不相见,如此便可不相恋。第二最好不相知,如此便可不相思。
第三最好不相伴,如此便可不相欠。第四最好不相惜,如此便可不相忆。
第五最好不相爱,如此便可不相弃。第六最好不相对,如此便可不相会。
第七最好不相误,如此便可不相负。第八最好不相许,如此便可不相续。
第九最好不相依,如此便可不相偎。第十最好不相遇,如此便可不相聚。
但曾相见便相知,相见何如不见时。安得与君相诀绝,免教生死作相思。
也确实是源自仓央嘉措,但经过后人的翻译和添加已经背离原意了。

抛开历史不谈,从文学的角度来看,其实上面这些诗歌都挺不错的,难怪无数少女为之倾倒啊!我个人最喜欢的还是吴虹飞唱的那首《仓央嘉措情歌》

那一天,我转动所有的经筒,不为超度不为来生,只为你的温暖。那一世,我转山转水,只为途中与你相见。
天上的仙鹤,借我洁白的翅膀,我不会远走高飞,飞到理塘就返回。山顶升起皎洁的月亮,你的脸庞浮在我心上。
当然,后来仓央嘉措的转世灵童在理塘被找到,于是“飞到理塘就返回”就成为仓央嘉措预言的证据了。亏我去川藏线的时候还路过理塘了呢……

孤独的托词

写在前面的话:《瓦尔登湖》中谦虚地用“穷困的托词”作为全书的正式开篇,这里斗胆套用一下作为本文的标题,同时也向这部伟大的作品致敬!

 

独自出门旅行,常被问道,你怎么是一个人?仿佛旅行这件事必须要两个人或者更多才能完成。我想他们大概是体会不到,很多风景只有一个人去欣赏的时候才能体会到它们那种特有的宁静,多一人便破坏掉这种气氛。

大约是现代人有着深入骨髓的寂寞和孤独感,很多人对孤独有着难以想象地抗拒和恐慌,甚至有的人像躲避瘟疫一样躲着它。他们不知道,孤独才是人的本性。我们怎么可以去抗拒本性呢?

人类不像蚂蚁那样,非群居动物。我们一出生多是孤独地来到这个世界,长大离开父母之后也要孤独地一个人四处去闯荡,到死也是要孤独地离开人世。纵使有志同道合的朋友,有白头偕老的妻子,可谁也无法真正地走入我们的内心世界。即使表面上始终有人陪伴,可内心深处永远都是孤独的。只是很多时候我们并不去在意这种孤独,或者这种孤独被外在的热闹所掩盖,而它实际上无时无刻不在,潜伏在心中,在将来的某时某刻或许就会爆发。

我的孤独是那种不被理解的孤独。我亦爱这热闹的世俗,更无法抗拒凡俗的异性之间的爱恋,可我一样也未尝得到。我朋友不少,知己不多,屈指可数。并非我刻意如此,冷漠孤傲,亦是内心深处始终有着他人无法理解的“特立独行”,难于表达,性格使然。遇到过不少谈得来的朋友,可多数也是停留在一个层次,对方无意深入,我亦无意继续。久而久之,我变得越发孤独。而且我这人偏偏又是爱憎分明,不圆滑,不妥协。我喜欢你便是真喜欢了,我讨厌你更是口无遮掩,毫不留情。这让我变得不好接近。

遇上心仪的姑娘,未尝不想前去搭讪,纵使内心千回百转,最终却也是一句话都说不出口,正所谓“发乎情,止于礼”。想起多年前,曾暗恋过一个姑娘,若不是友人相助我们或许一辈子都不会相识。相识之后大多也是沉默,不言爱情,稀里糊涂,等到分开才后悔,只能哀叹,“等闲变却故人心,却道故人心易变。”后来约莫喜欢上另一个姑娘,如遇知己,“信誓旦旦,不思其反”。因为她,我便知道了这世间的冷暖凄凉,我便成了这世间一个有情有义的男人。古人云,“只愿君心似我心,定不负相思意”,可她的心终究不是我的心,对此我无能为力。过了她,便是沧海桑田,永失我爱。我亦坚信这世上“也有爱情甜如蜜”,可是它与我无关。一切都太晚了,我已经孤独到不需要更多人理解!

这世间的每个人都是独立的个体,生而自由。即使是父母也不见得必须要对我们好,他们也有他们的生活,有时我甚至觉得没有我他们或许会过得更好。所以别人对我的好,我都感激不尽,一一看在眼里记在心里,也会一一去还。这也让我侥幸得到一些“好人”的称号。都说好人有好报,可我也没得到多少好报,有时甚至换来的是不理解。我早已经不在乎什么好报,更多的是害怕自己良心受责备。于你只为一个“理解万岁”,于己只求一个“问心无愧”。

我依然每天骄傲地活着,孤独地和这个生活进行着抗争,纵使被打得遍体鳞伤,也不肯屈服退让。张爱玲说,生活就像一袭华丽的袍子,上面爬满了虱子。我便是一个整天自己捉虱子的人,自得其乐,明知捉不完,倒也不知疲惫,越战越勇,感觉自己就像是堂吉诃德。以我多年的斗争经验来看,只有耐得住寂寞,才有可能斗得过生活。这也许正是为什么那么多的天才选择与寂寞为伍,和孤独为伴。除了那种“高处不胜寒”,还有他们才真正理解孤独的好处:

梭罗在《瓦尔登湖》里说,“大部分的时间内,我觉得寂寞是有益于健康的。我爱孤独,我没有碰到比寂寞更好的同伴了。”

叔本华的《关于独处》里写道,“青年人首要学习的一课,就是承受孤独,因为孤独是幸福、安乐的源泉。”

古罗马哲学家西塞罗说过,“一个完全依靠自己,一切称得上属于他的东西都存在于他的自身的人是不可能不幸福的。”

……

“孤单是一个人的狂欢,狂欢是一群人的孤单。”亦是同样的道理。所以即使身处灯红酒绿的酒吧,人头攒动的闹市,我亦可尽情享受这种孤单的滋味。这世上一切皆可负我,唯独孤独它不会,它一直是我忠实的好朋友,人类无法做到。

这个社会并没有给孤独的人足够的宽容,连歌词里都说“孤独的人是可耻的”。抑或是因为害怕寂寞的人太多,享受寂寞的人太少;远离孤独的人太多,理解孤独的人太少。这让我们显得格外与众不同,特立独行,四处躲避周遭投来的奇怪的眼光,感觉好像在与整个世界对立。到头来,我们虽不是什么“高山流水”,却也“曲高和寡”。

王小波写过《一只特立独行的猪》,每每读来都津津乐道。我想每一只特立独行的猪上辈子大抵都是一个看穿这大千世界的人,来世投胎宁可做猪也不肯为人。就像喂猪的人给猪安排好了生活一样,这个社会也给我们安排好了生活,只是我还不想屈服。瞧,我不也是一只特立独行的猪吗?时间就是那把杀猪的刀,我只是还不想被早早送进那屠宰场!

因为不去会死!

他和我们多数年轻人一样,本来有着一份舒适、而且在不少人看来羡慕的工作,如果再继续工作几年可以买车买房,结婚生子,然后知足地过一辈子。

可他偏偏没有这么做!放着舒适的办公室不坐,偏偏向往风餐露宿的旅途;放着安逸的生活不过,偏偏去冒各种风险去折腾自己;放着温暖的家不住,偏偏骑着自行车去用车轮丈量世界!这一去就是七年。

在很多人看来,他是个疯子。他们不理解,这么做到底是为了什么?不光你,我自己出门旅行时也常常问自己这个问题,反复思考,我觉得这句话最能概括这个问题的答案:“既然到了这世上,就要把世界好好的看看。不是为了谁,就是为了活了这一把,不看看这个世界长什么样子,就不甘心呐。”正如《瓦尔登湖》里所言,“免得到了临死的时候,才发现我根本就没有生活过。

其实很多时候,让我们放弃继续前进的并不是前方有多么困难,相反,而是后方有多么安逸,让你舍不得、放不下,迟迟不肯出发。困难再大我们咬咬牙也能克服,而安逸不是,我们都会从内心里不知不觉地屈从于它。旅途上不是没有艳遇,不是没有人陪伴,只是,哪怕姑娘再温柔,哪怕哥们儿们再义气,哪怕那酒再喝也不够,也要不回头,不回头地走下去!

七年之后,石田回到日本之后的故事,这本书里没有多讲。我很想知道,那时的他有一种怎样的心态?是看过了大千世界之后的激动?还是洗净了自己心灵后的平静如水?我知道的是,如果这个世界你都用骑行一遍了,那么这个世界上再也没有什么困难会打得倒你!我知道的是,如果整个世界你都走遍了,你肯定不会再为脚底下这一尺一寸的水泥地而斤斤计较!

所以,我非常欣赏高晓松的那句话:“在我和妹妹长大的这么多年里,我们分别走遍了世界,但都没买过一尺房子,因为我们始终坚信诗与远方才是我们的家园。

读完这本书的时候我正好又看了《搭车去柏林》,里面的那句话深深地震撼了我:“有些事情现在不做,一辈子也不会去做了。”这让我开始感到害怕,害怕哪一天我也会老去,不是人老,而是心老!等到结了婚生了孩子,看看身边贤惠的妻子,看看旁边可爱的孩子,到时我再想走,我还能动得了身吗?

我现在还年轻啊!我可不想多年以后等有了孙子的时候,当他问我“爷爷,你20多岁的时候都干了些什么?”的时候,我只能叹息“别提了,爷爷那时候还蜗居在水泥盒子里还贷呢!”我要骄傲地告诉他,“你爷爷我当年已经开始环游世界了!”

再不去我们就真的老了!

所以,以后别人再问你,“一定要去嘛?” 你要骄傲地回答他,“一定要去,因为不去会死!”

各种被相亲

作为一个适龄男青年,每次回家难免经历各种相亲。好在我爸妈够彪悍,早在我察觉之前已经为我挡住了各种被相亲。

一开始不知道,我爸妈连提都没给我提,看那样子也没认真提的打算。今天吃饭的时候聊起我去西藏的事来,然后我妈就开始了,一直谈到了我谈女朋友的问题,然后历数了这半年多来各种给我们家提亲的事。不说不知道啊,一说吓一跳,原来哥也是这么抢手。。。T_T

好在我妈无比强悍,我妈早在我知道这种事之前就已经先儿子之忧而忧,为我挡住了各种提亲的要求,其中有女大学生,护士等……理由堂而皇之,说我儿子这么优秀,凭什么找个这样的……囧,其实我当时很想插一句说,如果那个护士漂亮的话还是可以考虑的……可惜以我妈那种强悍的叙述方式我是连插话的机会都不会有的……

可是,按照现在姑娘的们观点,其实我连及格都算不上,我一没车,二没房,更可气的是压根就没有拥有这两种东西的欲望,更确切地说是深恶痛绝。因为我一直认为大多数人是愚蠢的,而他们追求的东西自然也是愚蠢,换句话说,我抵制的不是房子,不是车子,而是傻子。就像当那群傻逼抵制日货的时候我偏偏就去喜欢日货!无奈我认识的姑娘之中能意识到这一点的不屈指也可数。可见,要求一个女人既有胸又有脑是多么困难的一件事儿……

所以我觉得还是别相什么亲,以免浪费彼此的时间,否则见了面你觉得我是傻逼,我觉得你是傻逼,最后都恨不得拿起筷子、刀子、叉子来火拼了,何必自找不快呢?相亲不成还搞得遍体鳞伤……还不如去搞一夜情更安全一些。

更何况,我现在也没时间去谈恋爱啊!我想去骑海南岛,我想去骑台湾岛,我想去骑川藏线,我想去骑车绕大半个中国,路线我都想好了:从北京出发,经过石家庄,太原,经过西安,经过兰州,一直到新疆,到祖国的最西端,然后回青海,进西藏,走川藏线出去,到成都,到重庆,到广西,到广州,然后沿祖国的海岸线一路北上,到祖国的最东端去,到祖国的最北端去,最后回到祖国的首都!到时候我想看看还有哪个抵制日货的傻逼能有资格说比我还爱国!

我妈听着一愣一愣的,多半是因为很多地方她根本不知道。她说这得多长时间啊,我说怎么着也得一年吧!不辞职不行的。她对此表示十分淡定……我为有这么一个妈感到深深的骄傲!

月底下江南

十一没放假,照常上班了,我把假期挪到了月底。准备先回家一趟,然后去江南那边转一下,正好有不少同学和朋友在那里。一路没什么挑战性,算是纯休闲游了。

初步计划:

26号,一早到南京。

27号,绩溪,开始走徽杭古道徒步,晚上或第二天一早到杭州。

28,29号,杭州。

30,31号,宁波。

1号早上回北京上班。

一个人走,计划随时可能会变。我要充分利用一个人的好处。;-)

也有爱情甜如蜜

那谁快要结婚了,就是小红同学。认识这个姑娘好几年了,给我的印象一直都是大大咧咧的,没脾气,而且常以姐姐自居,用我的话说是动不动就“母仪天下”!瞧,这不等结婚生娃之后就可以实现“母仪天下”的夙愿了嘛?

这姑娘大概是从小就特没安全感,所以基本上没怎么出过我们泰安市。家在我们宁阳,然后大学是在泰安读的,毕业后马上就跑回家上班去了,她说宁愿在我们那种小地方待一辈子。

她和男朋友是大学认识的,好了很多年了,终于熬到结婚了,让人煞是羡慕。在这个“婚姻和爱情变得越来越短”的年代,能一直从恋爱走到结婚确实不容易,真心祝福他们!“有情人终成眷属”是多么美好的一件事!

还有那谁,简佳同学,已经远渡非洲织毛衣去了,这不到现在还没回京呢!走之前我就逗她说,你去非洲那种鸟不拉屎的地方干嘛,我们祖国又不是没有赵忠祥老师解说的《动物世界》,非得去那边看现场版的?可她就是铁了心要去看远在他乡的如意郎君,八匹马都拉不住!一个中国白妞儿,不远万里去非洲织毛衣,这是一种什么样的精神?

这个姑娘大我好几岁,按理说已经是传统意义上的“剩女”了。去年刚认识她那会儿应该是刚失恋没多久,要不怎么会闲着蛋疼跑去后海酒吧呢。经历了那么多不靠谱的人,相了那么多次亲,这次可总算是找到了一个到目前为止很靠谱的人了!姑娘,我只想说这是你应得的!

有一次吃饭时我问她,你喜欢一款类型的男人啊,我看看我手头上有没有给你介绍一下。她说喜欢外向的、善于交际的那种。我当时就不同意了,那种男人一般都不靠谱。后来,就是前两天,她从非洲给我发来几张照片,我一看他们俩的那张照片就乐了,一眼就能看出他是很老实内向的那种挨踢男!看,到最后你还是找了一个老实的吧!我语重心长地对她说:人靠谱而且真心对你好,那比什么都重要!衷心希望这一对也能一起走到最后。那谁,我还打算去吃你们的喜糖呢!

还有我们老大,就是Amankwah同学。当年稀里糊涂地去了广州那啥公司,可没过了多久就给我们收获了一个“大嫂”,当时我等就震惊了!真是迅雷不及掩耳盗铃之势!这家伙现在哪都不想去了,就一心一意待在广州陪大嫂了。

我们几个每次谈起老大都感叹良多,除了重色轻友就是……瞧这嫩草啃的……看来还是老男人吃香啊!记得我去广州的时候他们刚认识没多久,这不到现在已经两年了都。每次有哥们去看他们总是带回来大嫂如何贤惠以及老大如何幸福的消息,用我的话说大嫂可真是“持家有道,教子有方”啊!我看他们也快结婚了,我已经做了好去广州参加他们婚礼的心理准备了。老大,我看好你们哦!

瞧这一对又一对的……在这喧闹的人世间,物欲横流的社会,每次看到这让人羡慕的爱情,都感觉到一种窝心地甜美!莫不静好!

gcc 太聪明了!

gcc 越来越聪明了,有时候为了故意不让它优化某一部分代码(但同时还要开启-O!)我真可是费尽了心思。

举两个简单的例子来说明一下。一个是exp()的问题,不带-lm编译下面这段代码:

[c]

include

include

int main(void)
{
printf(“%lf”, exp(4.0));
return 0;
}
[/c]

你会发现可以得出正确的结果,没任何链接错误。它被预处理掉了吗?gcc -E告诉我们没有。那到底怎么回事呢?看一下生成的汇编,你会发现里面根本就没有call exp这样的指令!也就是说它被gcc在编译的时候处理了!这是因为像exp(4.0)这样的常量表达式是可以在编译的时候优化的,它的结果是个常量,所以gcc编译的时候就已经把这个值计算出来了,并把计算结果作为一个常量放到那个位置去了!为我们省去了一个函数调用!:-) 所以,如果你把上面的4.0换成一个double变量传递给exp(),你就会得到链接错误了。

另外一个例子是一个非常真实的例子。我们知道内核中有个著名的结构体叫struct skbuff,而我们公司内部的一个补丁中在某个函数中错误地把skbuff拼写成了skbuf!但编译和运行没任何问题!这个问题是后来别人在code review的时候才发现的!为什么呢?这明明应该通不过编译啊!我花费了不少时间去追踪这个问题,最后发现了问题的根源。为了方便叙述,我把问题的关键部分抽象成了下面的代码:

[c]
int foo(struct non_exist *n)
{
if (n)
return 0;
else
return 1;
}
[/c]

我们这么编译:gcc -c foo.c,你会发现我们只有警告,没有错误!警告我们可以忽略,因为我们只关心为什么不会有错误,换句话说,为什么gcc依旧可以成功地编译出代码来?仔细想一下你会明白,其实在foo()里面,我们根本就不用关心n到底是一个什么样的指针,只要知道它是一个指针就可以了!因为我们一没有对它进行dereference操作,二没有进行++或者—运算!而所有指针在特定的机器上长度是一定的。这正是为什么它可以通得过编译,但警告是肯定不会少的。;-)

如果你读过-O(或以上)生成的汇编的话,你还会发现一大坨gcc优化的例子,这可苦了我这种读汇编的人了,每次都得去猜gcc到底做了那些优化,不过这也相当有乐趣!

关于内存泄漏

不少编写用户空间程序的人都关心内存泄漏到底会造成多少影响。这里简单澄清一下。

无论用户空间是通过malloc()也好,mmap()也好,最终都是通过Linux内核管理的。只要内核没有bug,这些和这个进程相关的页面都是会被记录的,而且会在进程exit()的时候由Linux内核全部释放掉。所以对于运行时间不长的应用程序,有一些内存泄漏一般是没多大问题的。作为用户程序的编写者,如果释放内存真的很麻烦,或者说会让你的某一块代码变得很难读,你完全可以直接exit()。虽然很多时候我并不建议你这么做,道理很简单,因为你申请了资源就应该自己去释放,这不光是资源浪费的问题,而且是你代码逻辑和你作为开发者职责的问题。

实际上,Linux内核根本就不会注意到用户空间的泄漏不泄漏,它只关心你申请的这个页面有没有被它记录,所以进程退出时所有和此相关的内存页面都会被内核释放掉,管你是因为泄漏留下的还是用作其它用途的。

但是,你也知道,有些进程是不会主动退出的,那就是后台进程。这样的程序要是存在内存泄漏的话,还是可能会很浪费系统的内存资源的,因为内核没机会去释放这些页面,而且对用户空间的泄漏情况完全不知,它只会不停地给用户空间分配内存,直到用户空间地址耗尽或者物理内存趋近用完。

CVE-2009-0029 和 CVE-2010-3301

从我出去旅行到现在这段时间内,Linux内核似乎是漏洞频频啊,光我看到的安全漏洞就已经若干个了,有机会真想八一八这些安全漏洞。

CVE-2010-3301是其中一个。这个漏洞的成因是,在64位的内核上执行32位的系统调用时,作为传递系统调用号的%rax高32位未被清零处理,而且在进行比较的时候直接使用的%eax,导致高32位被忽略:

        cmpl $(IA32_NR_syscalls-1),%eax
        ja ia32_badsys
ia32_do_call:
        IA32_ARG_FIXUP
        call *ia32_sys_call_table(,%rax,8)

这样以来,通过静心构造的%rax就可以跳转到它想要的位置去!在这个exploit中,它就利用ptrace()来跟踪系统调用,并把计算好的想要跳转地址的偏移传递到%rax中,然后执行事先放置好的代码来提升权限!

修复方法很简单,要么把%rax的高位清零,要么比较的时候使用%rax。修复这个问题的commit是:

http://git.kernel.org/linus/36d001c70d8a0144ac1d038f6876c484849a74de
http://git.kernel.org/linus/eefdca043e8391dcd719711716492063030b55ac

和这个问题类似的问题之前也曾出现过,CVE-2009-0029,问题更严重,涉及很多的系统调用。不同的是,这个涉及64位的内核和64位的用户空间,来自用户空间的传递系统调用参数的寄存器的高32位同样没被清零,而带32位参数(比如int)的系统调用就会有问题,内核代码只会检查对它有意义的低32位,高32位就被忽略而直接传递到后面去了,这就会带来问题了。

问题的解决方法也很简单,就是要把这些寄存器高位清零。说起来简单,做起来难。要是和上面一样直接用汇编处理的话,参数的类型的信息就丢失了,因为你汇编里分不清它到底是32位还是64位;而如果用C处理的话,有那么多系统调用,一个一个处理?那不符合Linus的作风!他是怎么做的呢?用宏!而且用强制转化,把所有的32位参数声明为long,然后再强制转化成实际的类型,比如int。去看看SC_CASTx()和SC_LONGx()的定义就知道了:

[c]

define __SC_CAST1(t1, a1) (t1) a1

define __SC_LONG1(t1, a1) long a1

define __SYSCALL_DEFINEx(x, name, …)

    asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__));           
    static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__));       
    asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__))            
    {                                                               
            __SC_TEST##x(__VA_ARGS__);                              
            return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__));    
    }                                                               
    SYSCALL_ALIAS(sys##name, SyS##name);                            
    static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))

[/c]

可见Linus大神把宏用到了何等出神入化的地步。:-) 这也是为什么你在内核中看到系统调用都是用SYSCALL_DEFINEx()来定义了。