0%

Linux:Linux内核级安全开发基础(4)Linux系统调用的实现

Linux内核级安全开发基础

1.4 Linux系统调用的实现

1.系统调用入口地址表

每个系统调用在Linux内核中都有一个对应的处理函数——>完成该系统调用对应的服务功能

系统调用入口地址表

  • 实质:地址数组,下标:系统调用号,元素内容:对应系统调用的处理函数入口地址
2.中断机制和系统调用实现

系统调用接口实现的核心问题:CPU如何进行运行模式的切换,即CPU在用户态执行应用程序过程中,遇到系统调用请求,如何转向内核态执行操作系统中该系统调用对应的处理函数

中断机制

  • CPU收到中断信号,就会暂停当前的任务,自动转换到内核态进行相应的中断处理

  • 中断向量表:

    • 为了方便管理不同的中断,按照中断源不同将中断进行细分并编号,每个编号的中断对应相应的处理函数
    • 下标=编号,元素=中断处理函数的入口地址
  • 中断按处理方式不同可分为三类

    1. 硬件中断:严格意义上的中断,是外部设备与CPU进行通信的主要形式,也是CPU和外部设备能够并行工作的技术保证

    2. CPU执行异常:比如说CPU在执行指令过程中发现除以0的情况,就会发出异常信号,进行相应的异常处理

    3. 自陷trap:特殊的中断形式,为了让CPU在执行过程中能够主动切换到内核态执行,以进行相应的处理

      硬件中断和后面两种形式的中断在具体处理上有明显差别:

      • 硬件中断:中断处理完成,CPU会重新执行被中断的指令
      • 异常和自陷:中断处理完成,CPU直接执行下一条指令
  • 系统调用是借助于系统自陷实现的,通过执行相应的机器代码指令(自陷指令)产生中断信号,CPU自动从用户态切换到系统态进行处理。处理完成后,继续执行系统调用后面的指令

3.Linux系统调用的实现过程
  • Linux用来实现系统自陷的实际机器指令是 int x80,执行效果:激发一个x80号中断——>对应中断向量号128==是Linux系统为系统调用接口分配的中断编号,CPU执行该指令时,通过向量号将控制权转移给内核。

  • 程序员无需插入该汇编指令,只要像调用库函数一样调用系统调用即可。编译器在将源程序编译成可执行文件时,会生成相应的机器指令代码。

  • 具体过程:

    1. 编译出的目标程序在执行到intx 80位置时,CPU切换到系统态运行,将控制权转移给操作系统内核(即开始执行操作系统内核的代码)

    2. 内核中的代码查找中断向量表中x80号对应的中断处理函数,即系统调用总入口函数

      该函数大致任务:

      1. 保存寄存器等各种运行现场
      2. 从相应寄存器中获取系统调用号
      3. 根据系统调用号,从系统调用入口函数地址表获得处理函数的入口地址
      4. 调用处理函数,将结果保存在相应寄存器
      5. 完成系统调用出,从内核态返回,将结果反馈给用户进程,用户进程继续执行下一条指令