首先,TSS是一个历史性的疣.曾经有一段时间(又名:1980年代早期),英特尔的人们认为硬件上下文切换,而不是软件上下文切换,是一个好主意.他们错了.硬件上下文切换有几个显着的缺点,并且,由于它从未适当地实现,具有悲惨的性能.由于所有这一切,没有理智的操作系统甚至实现它,而且它甚至比分段更不便携.有关详细信息,请参阅OSDevers的模糊角落.
现在,关于任务状态部分.如果任何OS实现了硬件上下文切换,那么它的目的是表示"任务".可以将线程和进程都表示为"任务",但通常情况下,在我们使用硬件上下文切换的少数代码中,它代表了一个简单的过程.TSS将保存诸如任务的通用寄存器内容,控制寄存器(CR0,CR2,CR3和CR4;没有CR1),CPU标志和指令指针等等.
然而,在现实世界中,软件执行所有上下文切换,我们留下了104字节长的结构(几乎)无用.但是,正如我们所说的英特尔,它从未被弃用/删除,操作系统必须处理它.
问题实际上非常简单.假设您foo()在典型的用户模式过程中运行典型功能.突然,您,用户,按Windows/Meta/Super /但是您调用它键以启动您的邮件客户端.结果,中断请求(IRQ)从键盘发送到中断控制器(8259A PIC或IOAPIC).然后,中断控制器排列事物以触发CPU中断.CPU进入权限级别0,推送寄存器以及中断号,并调用内核模式代码来处理这种情况.等待!推东西?哪里?当然,在堆栈上!但是,从哪里获取堆栈指针以定义"堆栈"?
如果您碰巧使用用户模式堆栈指针,则会发生错误,并且可以使用巨大的安全漏洞.如果堆栈指针指向无效地址会发生什么?它可能发生.毕竟,严格来说,堆栈指针只是另一个通用寄存器,并且已知汇编程序员以硬核方式使用它.
尝试在那里推送东西会产生CPU异常,真好!并且,由于双重故障(尝试处理中断时发生的异常)将再次尝试推翻无效指针,操作系统的最糟糕的噩梦变为真:三重故障.你有没有看到你的计算机突然重启而没有任何事先的建议?这是一个三重故障(或电源故障).操作系统没有改变来处理三重故障,它只是重新启动一切.
太棒了,系统重新启动了.但是,更糟糕的事情可能发生了.如果攻击者故意编写了一个关键内核变量(!)的地址,并将他想要的值以正确的顺序写入那里,那么让最大的权限提升利用,因为获得超级用户权限变得比以往更容易!GDB,内核的配置(找到了/proc/config.gz,内核编译的GCC版本绰绰有余).
现在,回到TSS,前面提到的结构包含在特权级别3(用户模式)下在中断时加载的堆栈指针和堆栈段寄存器的值.内核将此设置为指向kernel-land中的安全堆栈.因此,系统中每个线程都有一个"内核堆栈",系统中每个逻辑CPU都有一个TSS.在线程切换时,内核只在正确的TSS中更改这两个变量.不,每个逻辑CPU不能有一个内核堆栈,因为内核本身可能被抢占(大部分时间).
我希望这对你有所启发!