IA32的分段机制中,特权级总共有4个特权级别,分别是0,1,2,3。数字越小表示特权级越大。DPL和RPL都是用来表示特权级别的。
见上图 ,较为核心的代码和数据,被放在特权级较高的层级中。处理器将这样的机制来避免低特权级的任务在不被允许的情况下访问位于高特权级的段。如果处理器检测到一个访问请求不是合法的,将会产生常规保护错误(#GP)
处理器通过识别CPL、DPL、RPL这3中特权级别进行特权级别检查。
1.CPL(Current Privilege Level)
CPL是当前执行的程序或任务的特权级。它被存储在CS和SS的第0位和第1位上。在通常情况下,CPL等于代码所在的段的特权级。当程序转移到不同特权级的代码段时,处理器将改变CPL。
但是有个例外是一致代码段,一致代码段可以被相同或者更低特权级的代码访问,当处理器访问一个与CPL特权级不同的一致代码段时,CPL不会改变。
2.DPL(Descriptor Privilege level)
DPL表示段或者门的特权级。它被存储在段描述符或者门描述符的DPL中,当当前代码段试图访问一个段或者门时,DPL将会和CPL以及段或门选择子的RPL相比较。下面是各种类型的段或者门的情况:
数据段:
DPL规定可以访问此段的最低特权级。只有运行在CPL<=DPL程序才有权访问。比如一个数据段的DPL是1,只有运行在CPL为0或者1的程序才有权访问。
非一致代码段(不使用调用门):
DPL规定访问此段的特权级。只有CPL=DPL的程序才可以访问。比如,一个非一致代码段的特权级为0,只有CPL为0的程序才可以访问。
调用门:
DPL规定可以访问此段的最低特权级。(这与数据段的规则是一致的)
一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高特权级。比如一个一致代码段的DPL是2,那么CPL为0和1的程序将无法访问此段。
TSS:
DPL规定了可以访问次TSS的最低特权级(与数据段的规则是一致的)
3.RPL(Requested Privilege Level)
RPL是通过段选择子的第0位和第1位表现出来的。操作系统过程往往用RPL来避免低特权级应用程序访问高特权级段内的数据。当操作系统过程(被调用过程)从一个应用程序(调用过程)接受选择子时,将会把选择子的RPL设成调用者的特权级。于是,当操作系统用这个选择子区访问相应的段时,处理器将会用调用过程的特权级(RPL),而不是更高的操作系统过程的特权级(CPL)进行特权检验。这样,RPL就保证了操作系统不会越俎代庖的代表一个程序区访问一个段,除非这个程序本身是有权限的。
===============================================================
特权级转移:
我们可以通过jmp或call进行直接转移,转移的条件如下
1.目标是非一致代码段:CPL = DPL(目标)并且RPL<=DPL(目标)
2.目标是一致代码段:CPL>=DPL(目标) RPL不做检查。
当转移到一致代码段中后,CPL会被延续下来,而不会变成目标代码段的DPL。
通过jmp和call所能进行的代码段间的转移时非常有限的:
对于非一致代码段,只能在相同特权级别的代码之间转移。
对于一致代码段也最多能从低到高,而且CPL不会改变。
如果想自由的进行不同特权级之间的转移,需要其他几种方式,即运用门描述符或者TSS。