今年早些时候,我新加入了一个大多数从事研究社会科学和政治小组,然后我得向他们介绍一下我目前正在从事的工作。在这大概有10个人的小组中,有一两个人对内核的概念是有一个初步的了解(实际上因为他们是工科学生),但是小组中的其他人却对内核茫然无知—他们等着我给他们说明解释一下。
那么,对于那些有点基本概念的工科生,首选方法就是打一个有关于汽车的比方(至少得是男性听众)。然而,实际上你能把汽车上的什么东西来比作内核呢?你是不能直接把内核比作发动机,或者底盘,甚至是车辆行驶的道路。当你试着去解释一个内核程序员能够利用操作系统做什么的时候就更糟糕了。在将汽车作为喻体时,内核到底是什么呢?一个内核程序员并不能直接定义为一个技工。那么,定义为汽车设计师之类的吗?经过长时间的断断续续的解释和迟疑,我试着先向小组中的女孩们解释,这就像是内核开发者为奔跑的汽车设计物理定律。很遗憾,她们仍然不相信。
你有更好地解释吗?
《黑客帝国(The Matrix)》于1999年上映的,因此,很快我就对操作系统开始感兴趣,最后我还在FreeBSD(一种免费的Unix系统)项目中成为一名内核开发员。但是同时,我一直学习并痴迷于《黑客帝国(The Matrix)》,花费了大量的时间。
在二十一世纪初的某个时候,大概是在03或04年,我写下了一篇文章,我将《黑客帝国》中人物和他们发生的事以及它的续集与一个(虚拟的)操作系统做一个系统的类比。为了将久远的这篇文章保存下来,防止内容的丢失在被遗忘的服务器上,就将它迁移到云上,我在下面复制粘贴了该文章的初始内容。提示:你可以将该比喻引申的更远。
既然操作系统的设计,实现和维护是我最大的兴趣之一,而且我在第一时间就观看了《黑客帝国》,于是便对电影里的一些概念进行了思考,并认为它们与操作系统存在某种程度上的相似之处:
Matrix世界:
相当于一个正在运行的具有用户空间的操作系统(我们人类居住的普通世界,内核(“Matrix”本身))。显然的,这是一个颇有缺陷的操作系统。。。
民众:
相当于进程,包括内核进程和用户进程。一般进程,“非特权”进程和具有root权限的后台进程(“特工”)还是有很大的区别。具有root权限的后台进程可以使用特权端口,销毁随机进程,管理内存等等。
Matrix:
相当于内核。它看上去是基于消息传递的内核结构,而并非是微内核结构(尽管它们具有微内核的某些部分,比如拥有大量内核进程,进程之间都是严格独立的,以及已提到的消息传递机制)。内核管理所有的进程,以及进程上的操作(比如保持进程活跃,为进程服务,回收进程)。但是这仍有一个明显的安全缺陷:某些用户进程能够将它们的部分代码传送到内核空间并执行(因为一个bug)。只有某些系统调用受到影响(类似于 ”phones”),这种扩大了的特权篡改了用户进程的返回栈,因此,如果该进程接收到一个信号,它会产生段错误并被作为垃圾回收(你如果在Matrix中被杀掉的话,那么你就真的死掉了)。
先知(Oracle):
相当于进程(任务)调度器。拥有处理监听(资源利用率)的所有数据以及提前(这很显然)知道怎样对它们进行最优调度。
特工(Agents):
相当于系统监控/入侵防护/具有启发式操作的防护系统(IDS(入侵检测系统)/IPS(信息处理系统))。它们中绝大多数都有一个内核部分(或内核模块)但基本上却是那些具有超级用户特权的后台进程在用户空间运行。它们的职责是发现试图入侵系统安全的进程并销毁掉。
列车员:
相当于内核和用户空间的网关/信息传递队列。你如果想要合法地在用户空间和内核进行数据传递必须通过这里来进行。当然,你也可能永远被困在排队队列中。
邪恶宗师—梅罗纹奇(Merovingian):
相当于网络/IPC(进程间通信)栈。它的职责是掌握进程之间都发生了什么。输入/输出数据的一个偶然错误将以一个bug的形式表现出来。
“鬼魅”(Ghost):
相当于老版本API/KPI的兼容器。由于历史原因,这些代码并不完善,但与某些内核进程相连的代码却不应该不完整。
“建筑师”(Architect):
相当于硬件上的内核监控(管理者),负责监控进程,销毁那些“畸形”进程并对销毁的进程进行重启。由于它是一个实时的具有高度可靠性的系统,在硬件上进行调试和监控显然具有最高的优先级,而且还绝对是可靠的(因此,为了降低出错的可能性,也降低它的复杂性)。由于它频繁地进行可用性检查,造成了过度的错误配置,消耗了太多的资源,因此影响到了操作系统的正常运作。
关键人物—制钥者:
相当于安全/特权子系统。它很稳定,但不幸的是需要依赖不完善的VM(虚拟内存)系统和IPC系统,因此它可被进程利用来获取更多的特权。
Matrix系统设计:
在系统高度负载的情况下(大量的进程,频繁的内存读写),VM(虚拟内存)系统,进程管理系统和调度器之间有一个设计缺陷。这是一个复合错误,至少会导致三种问题的产生:1、内存页被破坏或者内存页分配给那些不属于它们的进程。由于内核和用户空间共享虚拟内存,为了防止敏感数据的暴露,提高安全性,任何一方的进程都可以因为得到另一方的内存页而被销毁。2、进程间通信,这是非常糟糕的,甚至比进程的数据结构被破坏或者内存装载太频繁而造成死锁,而不得不等待缓冲区还要糟糕。3、系统监控变得不稳定,循环地销毁和重启进程,察觉不到这样的操作会额外增加内存和进程的负担而变得更糟糕,最后极大地增长了进程间虚拟内存页被破坏的速度。
史密斯特工:
相当于有特权的IPC后台程序,具有部分内核模块功能。它与内核模块关系密切,且能够不通过完整性检查而与内核共享数据结构。一旦它被另一个特权进程销毁掉,它也能藏身于一个系统调用中间以便于监控者重启它,此时它的进程描述符也被破坏,这样使得它的大部分程序代码将在内核中执行。它将继续以这种受损状态长时间工作,锲入到一个循环中,并将进程错误地标记为安全漏洞,同时重写它的某些内存页。
尼奥(Neo):
最初是一个用户空间的网络服务进程,虚拟内存的损坏导致它被赋予了超级用户的特权以及具有CPU高优先级。最后它得到可执行的内存页与IDS进程Simth的混合,但却不是数据页。很快它也开始销毁进程,包括Smith和它自己被损坏的部分。
结局:
最后Smith进程试图杀死调度者进程,但由于他本是也是通过该调度者调度的,他并不能这么做。系统变得畸形是因为调度者不能再执行任务,包括中断服务,但是在调度者的虚拟内存镜像(同样该镜像也偶然地与Neo进程进行了部分共享)里的部分Smith代码却仍然可以执行。由于只有两个进程可以运行,他们都想杀掉对方。与此同时,由于没有中断服务,硬件的监视时钟别唤醒,它插入了一个NMI(不可屏蔽的中断),这样就又唤醒了监控系统。这就使得系统处于临界状态并开始杀掉所有的进程,然后重启被杀掉的进程来使系统再次启动。结束!
分析总结
在操作系统的设计时候有一个内在的缺陷,特别是在虚拟内存,进程间通信和监控子系统这几方面,这将导致进程间的全局内存被破坏以及在少量进程的地址空间产生致命的缺陷。
建议:
要保证适宜的进程优先级,必须进行更多的微调,减少优先级反转和失衡。很可能要重写虚拟内存系统,开发消耗更少资源的版本来取代IDS系统。如果系统负载处于某个阀值之上,系统监视器必须要进行修正,而不会再启动大量的操作。
好了,这就是一篇有关The Matrix且不涉及任何形式“自由意志”的阐述。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/45219.html