首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >glibc/NPTL/Linux健壮互斥中的竞争条件?

glibc/NPTL/Linux健壮互斥中的竞争条件?
EN

Stack Overflow用户
提问于 2012-08-14 11:34:08
回答 2查看 1.1K关注 0票数 16

在2010年关于Automatically release mutex on crashes in Unix问题的评论中,jilles声称:

glibc强大的互斥量之所以如此之快,是因为glibc采用了危险的捷径。当内核将互斥锁标记为“将导致EOWNERDEAD”时,不能保证互斥锁仍然存在。如果互斥锁被销毁,内存被替换为内存映射文件,该文件恰好在正确的位置包含最后一个拥有线程的ID,并且最后一个拥有线程在写入锁字之后(但在从拥有互斥锁的列表中完全删除互斥锁之前)终止,则该文件将被损坏。Solaris和will-be-FreeBSD9健壮的互斥锁速度较慢,因为它们不想冒这个风险。

我不能理解这种说法,因为销毁互斥是不合法的,除非它是解锁的(因此不在任何线程的健壮列表中)。我也找不到任何搜索这样的bug/问题的参考资料。这种说法仅仅是错误的吗?

我这么问的原因和我感兴趣的原因是,这与我自己的实现的正确性有关,这些实现是基于相同的Linux robust-mutex原语构建的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-18 06:45:24

FreeBSD pthread开发人员David Xu对比赛的描述:http://lists.freebsd.org/pipermail/svn-src-user/2010-November/003668.html

我不认为munmap/mmap周期对于比赛是严格要求的。这块共享内存也可能被用于不同的用途。这并不常见,但却是有效的。

正如该消息中提到的,如果具有不同权限的线程访问共同的健壮互斥锁,则会产生更多的“乐趣”。因为所拥有的健壮互斥锁列表的节点在互斥锁本身中,所以具有低权限的线程可能会破坏高权限线程的列表。这很容易被利用来使高特权线程崩溃,在极少数情况下,这可能会导致高特权线程的内存被破坏。显然,Linux的强大互斥锁只为具有相同特权的线程而设计。通过将健壮的列表完全设置为线程内存中的数组,而不是链表,可以很容易地避免这种情况。

票数 6
EN

Stack Overflow用户

发布于 2012-08-18 02:34:38

我想我找到了这场比赛,它确实非常丑陋。它是这样的:

线程A持有健壮的互斥锁并将其解锁。基本步骤是:

  1. 将其放入线程健壮列表头的“挂起”槽中。
  2. 将其从当前线程持有的健壮互斥锁的链表中删除。
  3. 解锁互斥锁。
  4. 清除线程健壮列表头的“挂起”槽。

问题是,在第3步和第4步之间,同一进程中的另一个线程可以获取互斥锁,然后解锁它,并(正确地)认为自己是互斥锁的最终用户,销毁并释放/munmap它。在此之后,如果进程中的任何线程创建了文件、设备或共享内存的共享映射,并且恰好分配了相同的地址,并且该位置的值恰好与仍在解锁步骤3和4之间的线程的pid匹配,那么就会出现这样的情况:如果进程被终止,内核将通过设置它认为是互斥锁所有者id的32位整数的高位来破坏映射的文件。

解决方案是在上面的步骤2和4之间保持对mmap/munmap的全局锁定,这与我对此问题的回答中描述的屏障问题的解决方案完全相同:

Can a correct fail-safe process-shared barrier be implemented on Linux?

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11945429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档