科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道利用异常表处理Linux内核态缺页异常 (2)

利用异常表处理Linux内核态缺页异常 (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

运行在核心态的进程经常需要访问用户地址空间的内容,但是谁都无法保证内核所得到的这些从用户空间传入的地址信息是"合法"的。为了保护内核不受错误信息的攻击,需要验证这些从用户空间传入的地址信息的正确性。

作者:asdkj 来源:赛迪网技术社区 2007年10月28日

关键字: 异常 内核 Linux

  • 评论
  • 分享微博
  • 分享邮件

内核缺页异常处理

运行在核心态的进程经常需要访问用户地址空间的内容,但是谁都无法保证内核所得到的这些从用户空间传入的地址信息是"合法"的。为了保护内核不受错误信息的攻击,需要验证这些从用户空间传入的地址信息的正确性。

在老版本的Linux中,这个工作是通过函数verify_area来完成的:

extern inline int verify_area(int type, const void * addr, unsigned long size)
  

该函数验证了是否可以以type中说明的访问类型(read or write)访问从地址addr开始、大小为size的一块虚拟存储区域。为了做到这一点,verify_read首先需要找到包含地址addr的虚拟存储区域(vma)。一般的情况下(正确运行的程序)这个测试都会成功返回,在少数情况下才会出现失败的情况。也就是说,大部分的情况下内核在一些无用的验证操作上花费了不算短的时间,这从操作系统运行效率的角度来说是不可接受的。

为了解决这个问题,现在的Linux设计中将验证的工作交给虚存中的硬件设备来完成。当系统启动分页机制以后,如果一条指令的虚拟地址所对应的页框(page frame)不在内存中或者访问的类型有错误,就会发生缺页异常。处理器把引起缺页异常的虚拟地址装到寄存器CR2中,并提供一个出错码,指示引起缺页异常的存储器访问的类型,随后调用Linux的缺页异常处理函数进行处理。

Linux中进行缺页异常处理的函数如下:

 asmlinkage void do_page_fault
(struct pt_regs *regs, unsigned long error_code)
  {
  ……………………
   __asm__("movl %%cr2,%0":"=r" (address));
   ……………………
   vma = find_vma(mm, address);
   if (!vma)
   goto bad_area;
   if (vma->vm_start <= address)
   goto good_area;
   if (!(vma->vm_flags & VM_GROWSDOWN))
   goto bad_area;
   if (error_code & 4) {
   if (address + 32 < regs->esp)
   goto bad_area;
   ……………………
  bad_area:
   ……………………
  no_context:
   /* Are we prepared to handle this kernel fault? */
   if ((fixup = search_exception_table(regs->eip)) != 0) {
   regs->eip = fixup;
   return;
   }
   ………………………
  }
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章