x86架构中特权级

        特权级,可以分为三种;第一、描述符中的特权级DPL,表示这个段的特权;第二、选择子的RPL表示请求方的特权级;第三、当前特权级,表示正在执行的代码段所具有的特权;下面有关特权级知识的总结:


        第一、对于数据段来说,特权级DPL表示了可以访问该数据的最低特权。若数据段的DPL为1,那么只有特权级为0或1的程序才能访问他;


        第二、特权指令,为了安全和效率有些指令是只能有特权级为0的代码执行的,比如:lgdt指令;


        第三、若高特权级代码段定义为非依从(即:代码段描述符中TYPE中第三位C位依从位为0),那么处理器只能在同特权级下的代码间转移;CPL = DPL,RPL = DPL;


        第四、若高特权级代码段定义为依从(即:代码段描述符中TYPE中第三位C位依从位为1),那么可以从低特权级程序中转移到高特权级程序中(即:CPL数值 >= 目标代码段描述符中的DPL)。比如,当一个依从代码段特权级为2,那么只有特权级为2,3的程序才能转移到给依从代码中去执行。所谓依从是指当一个特权级为3的程序调用一个特权级为0的程序时,当前特权级CPL不改变,cs中的CPL字段不改变。也即是被调用程序依从于调用程序,就是说被调用程序特权依附调用程序特权,所以当前特权级CPL不改变。看到这里会发现代码段和数据段有点不一样,数据段是要求特权级比自己高的程序才能访问,代码段则是要求比自己低的程序才能调用它,虽然有点不一样,但目的都是一样的,都是为了安全考虑。因为特权级越高的越安全,处理器是一定不会把控制权交给比当前特权级低的程序去运行的。 CPL数值 >= DPL,RPL数值 >= DPL;


        第五、门描述符,用于不同特权级代码之间的转移控制;调用门有两种使用方法:jmp far 从低特权级代码转移到高特权级代码(和是否依从没关系),当前特权级不改变(其实类似于低特权级代码转移到高特权级依从代码);call  far 从低特权级代码转移到高特权级代码(和是否依从没关系),但是会改变当前特权级,当前特权级会提升到目标特权级,也就是说会在高特权级上执行程序,除了返回外,不允许从特权级高的代码段转移到特权级低的代码段(这是绝对禁止的);


        在使用调用门call far中会存在一个问题,那就是当特权级为3的程序使用调用门call  far调用特权级为0的程序中去读取特权为2的数据段数据时,因为特权级为3的程序是不能读取特权级为2的数据段数据的,但这里通过使用门调用,提升了当前特权级,所以是允许的。但是为了防止恶意程序使用这个漏洞,所以有在选择子中添加了一个RPL请求特权级,这个RPL可以说才是真正想读取数据的程序特权级,而特权级为0的例程只是一个被人利用的工具而已。在例程中会用指令获取到调用该例程的选择子中的RPL(这里是3),当每次引用一个段时都会把开始获取到的RPL添加在选择子中(这里当要引用数据段时,RPL位会用调用者的RPL,也即是3)。其实调用门中call far虽然提升了代码的特权级,但是在引用其他段时,还是要还原他的本来面目,也就是本来的特权级。当然这都是由操作系统设计者自己决定的。


        第六、当把选择子传送到数据段寄存器时,要求:当前特权级高于或者等于数据段描述符的DPL,CPL数值 <= DPL数值;请求特权级也要高于或者等于数据段描述符的DPL,RPL数值 <= DPL数值;


        第七、对于堆栈的特权,则更为特别点,要求RPL = DPL = CPL;比如,当特权级3的程序调用特权级0的程序,则要定义特权级0,特权级1,特权级2,特权级3,共四个堆栈段;


转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/42395293

        

你可能感兴趣的:(操作系统)