基于软件的TSS上下文切换如何工作?

时间:2016-03-06 14:54:19

标签: x86 operating-system

我想知道TSS(任务状态段)的简单解释以及它如何用于执行基于软件的上下文切换。

1 个答案:

答案 0 :(得分:5)

首先, TSS是一个历史性的疣。曾经有一段时间(a.k.a:1980年代早期),英特尔的人们认为硬件上下文切换,而不是软件上下文切换,是一个好主意。他们错了。硬件上下文切换有几个显着的缺点,并且,由于它从未适当地实现,具有悲惨的性能。由于所有这一切,没有理智的操作系统甚至实现它,而且它甚至比分段更不便携。有关详细信息,请参阅the obscure corner of 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不能有一个内核堆栈,因为内核本身可能被抢占(大部分时间)。

我希望这能为你带来一些启示!