Linux系统调用和内核模式

lyn*_*nks 6 security system-calls

我知道存在系统调用以提供对用户空间中不允许的功能的访问,例如使用read()系统调用访问HDD .我也理解这些是以库调用的形式由用户模式层抽象出来的,例如fread(),以提供跨硬件的兼容性.

所以从应用程序开发人员的角度来看,我们有类似的东西 ;

//library    //syscall   //k_driver    //device_driver
fread()  ->  read()  ->  k_read()  ->  d_read()
Run Code Online (Sandbox Code Playgroud)

我的问题是; 是什么阻止我内联的所有指令fread()read()功能直接进入我的程序?说明是一样的,所以CPU应该以相同的方式运行?我没有尝试过,但我认为这是因为某些原因我失踪了.否则任何应用程序都可以获得任意内核模式操

TL; DR:什么允许系统调用"进入"应用程序无法复制的内核模式?

jll*_*gre 8

系统调用本身不会进入内核.更准确地说,例如,就您的应用程序而言,您调用的读取函数仍然是库调用.什么read(2)内部所做的是调用使用一些中断或实际的系统调用syscall(2)的汇编指令,根据不同的CPU架构和操作系统.

这是用户态代码执行特权代码的唯一方法,但它是间接的方式.userland和内核代码在不同的上下文中执行.

这意味着您无法将内核源代码添加到用户态代码中,并希望它可以执行任何有用但崩溃的操作.特别是,内核代码可以访问与硬件交互所需的物理内存地址.Userland代码仅限于访问不具备此功能的虚拟内存空间.此外,允许执行的用户区代码指令是CPU支持的指令的子集.几个I/O,中断和虚拟化相关指令是禁止代码的示例.它们被称为特权指令,需要处于较低的环或管理程序模式,具体取决于CPU架构.

  • 啊,现在越来越清楚了。执行内核模式指令的唯一方法是通过中断描述符表。因此,您要么必须写入 IDT,要么写入 IDT 指向的内存区域。两者都不会映射到用户模式进程的可写状态。谢谢你们俩。 (2认同)