规则
不通过门,规则如下:
- 访问数据段,访问者的特权等级要高于或等于受访者的特权等级。
- 访问代码段,访问者的特权等级要等于受访者的特权等级。访问者的特权等级高于或小于受访者的特权等级都不行。
写成公式,如下:
- 数值上,CPL <= DPL && RPL <= DPL。
- 数值上,CPL = DPL = RPL。
RPL为什么要参与运算?为了防止用户非法获取高于它的特权等级的数据。
例如,用户进程的CPL是3,请求DPL=0的内核帮助它完成一个操作。用户进程提交一个选择子参数后,进入内核后,CPL=0,拥有最高特权等级,用户进程此时可以读写它本来无权访问的资源。如果让用户进程的RPL参与特权等级检查,就能识别出它的真实等级。即使CPL满足条件,RPL也不满足,从而能防止用户进程非常操作。
疑问
用户进程的RPL从哪里获取?
为什么
数据段
给数据段设置特权等级,就是为了让特定特权等级才能访问它,让另外一些特权等级不能访问它。如果任何特权等级的访问者都能访问数据段,给数据段设置特权等级就失去了意义。
为什么访问者的特权等级比数据段的特权等级高才能访问数据段?这是人为设置的规则而已,如果你愿意,也可以设置为“访问者的特权等级比数据段的特权等级低才能访问数据”。这样的话,整个特权等级都需要调整为“访问者特权级比受访者特权级低才能访问受访者“。
代码段
代码段是指令,在CPU上执行,完成功能。低特权级的代码段能访问的资源、能完成的功能,高特权级都能访问、都能完成。高特权级的代码段不需要访问低特权级的代码段去访问资源或完成功能。
代码段也是一种资源,也不能被随意访问。只能被特权级高于自身的代码段访问。
概况一下,低等级代码段无权访问高等级代码段,高等级代码段不需要多此一举地访问低等级代码段,所以,若访问者和受访者都是代码段,只有二者是同特权等级才能访问。
低特权级如何访问高特权级
低特权级访问者访问高特权级受访者,是普遍发生的。例如,用户进程向硬盘读写数据,必须通过操作系统。可是,又有上面的规则的限制。低特权级访问者怎么才能访问高特权级访问者呢?
代码段
一致性代码段
如果受访者是一致性代码段,低特权级访问者可以直接访问受访者。
非一致性代码段
如果受访者是非一致性代码段,低特权级访问者需要通过”门“访问受访者。
为了叙述方便,必须引入CPL、RPL、DPL这些术语了。
在选择子中,含有RPL。在描述符中,含有DPL。CPL是cs.RPL。
使用门,涉及的元素有:门选择子、门描述符、门描述符指向的段选择子、门描述符指向的段选择子指向的段描述符。
参与特权等级检查的元素有:
- CPL:CS.RPL。
- RPL:门选择子的RPL。
- DPL:门描述符的DPL。
- DPL_CODE:门描述符指向的段选择子指向的段描述符的DPL。
通过特权等级检查的条件有两个:
- 数值上,CPL <= DPL
&& RPL <= DPL。 - 数值上,CPL >= DPL_CODE
&& RPL >= DPL_CODE。
特权等级只有4个等级,从高到低依次是:0、1、2、3。
门作为一种资源,访问者的特权等级必须高于或等于它,才能访问它。
若访问者的特权等级高于等于受访者的特权等级,根本不需要使用门来访问。第二个条件,是区分前面的假设情况而设定的。
疑问
不理解为什么”RPL不需要参与运算“。
数据段
低特权等级访问者永远无权访问特权等级高于它的数据段。