(int)PCPU_GET(curpcb)->pcb_onfault;
goto out;
}
break;
......
} /* end switch */
......
} /* end else */
......
out:
return;
}
对于copyin()产生的错误,"general protection fault"或"stack fault"
或"segment not present fault",都由这段代码处理 。
由于在进入copyin()时设置了curpcb->pcb_onfault,这里将异常处理程序退出时
继续运行的eip指针设置为copyin_fault,于是,当异常返回后,程序控制将到达
copyin_fault 。
代码:
ALIGN_TEXT
copyin_fault:
popl 韎
popl %esi
movl PCPU(CURPCB),韝
movl $0,PCB_ONFAULT(韝)
movl $EFAULT,陎
ret
在这里,恢复寄存器,清除curpcb->pcb_onfault,返回EFAULT.
注意,此时的核心栈与拷贝成功时的核心栈是相同的,这是因为前述trap()函数
修改%eip后,程序只是将本来应该继续执行拷贝错误语句改为执行copyin_fault,
异常处理程序返回后的核心栈并没有变化 。因此,内核将顺着copyin()后的代码执行,
就好象根本没有发生过异常一样 。
参考文献:
[1] Sinan "noir" Eren, "Smashing The Kernel Stack For Fun And Profit", phrack60-06
推荐阅读
- freebsd系统日志与备份
- 图形化的FreeBSD 5.1工作站
- FreeBSD4.8 IPFW How to!
- 使用串口控制FreeBSD Using Serial Console in FreeBSD
- FreeBSD下架设CS服务器
- FreeBSD 数据迁移方法
- 如何查看FreeBSD的系统日志
- Implement FreeBSD Kernel PPPoe
- freebsd mount挂载iso
- 初学FreeBSD您必須知道的事