考虑由多个进程访问的文件;进程将文件映射到内存,然后使用无锁操作进行同步(例如,使用原子添加来分配要写入的文件中的偏移量)。
原子操作可能是无锁的,但不是没有等待的。例如,在x86上,原子-max将被实现为一个比较-交换循环(获取以前的值,计算新的最大值,比较-交换,如果以前的值发生变化,则重复)。现在,恶意进程可能会使用写操作来敲击内存位置,从而使比较-交换不断失败,从而永远阻塞其他进程。
这是我需要保护的真正问题吗?或者现代处理器不可预测的时间使得这样的攻击变得不可能?
发布于 2019-03-25 13:44:40
最有趣的问题。
理论上,如果我们故意让CAS (比较和交换)总是失败的话,这样的攻击是可能的。
为了实现这一点(从硬件的角度来看),底层硬件应该允许所有相互竞争的线程失败,这通常是不应该的,因为对于所有线程可能失败的CAS可能导致实时锁定情况(以及非确定性行为)。
此外,在重新尝试CAS之前,应该使用诸如指数后退(如以太网协议)之类的技术。
从软件的角度来看,如果不确定背后的硬件,可以确保使用诸如AtomicX.compareAndSet (JAVA 7,8)之类的东西,而不是AtomicX.weakCompareAndSet,后者实际上确保排除了所有线程的同时故障。
例如,win32实现是安全的:
void LockFreeQueue::push(Node* newHead)
{
for (;;)
{
// Copy shared var to local.
Node* oldHead = m_Head;
// Do some work, not yet visible to other threads.
newHead->next = oldHead;
// Attempt to publish changes to the shared variable.
// If the shared var hasn't changed, the CAS succeeds and we return.
// Otherwise, repeat.
if (_InterlockedCompareExchange(&m_Head, newHead, oldHead) == oldHead)
return;
}
}上面的循环是免费的,因为如果一个线程的测试失败了,它就意味着它一定对另一个线程成功了。
https://security.stackexchange.com/questions/206045
复制相似问题