【问题标题】:can I change pthread_create to map new threads not in the stack?我可以更改 pthread_create 以映射不在堆栈中的新线程吗?
【发布时间】:2020-07-18 15:13:23
【问题描述】:

我正在使用glibc-2.27 中的pthread.h 库,当我的进程调用pthread_create() 18 次或更多次(它应该是一个繁重的多线程应用程序)时,进程被中止并显示错误消息:

*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

我在调试过程中做了一些strace,我找到了原因。显然,所有对 mmap() 的隐式调用作为 pthread_create() 的一部分如下所示:

mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f6de43fa000

人们可以注意到MAP_STACK 标志,它表示:

在适合进程或线程堆栈的地址分配映射。 该标志目前是无操作的,但在 glibc 线程实现中使用,因此如果某些架构需要对堆栈分配进行特殊处理,以后可以透明地为 glibc 实现支持。

man mmap 在我的系统上 - Ubuntu 18.04 LTS)

可以配置pthread_create 调用不这样做吗?或者可能使用brk 或其他方式自动增加数据段?

感谢您的帮助!

【问题讨论】:

标签: c pthreads clone glibc mmap


【解决方案1】:

您的问题极不可能与此 MAP_STACK 标志有关。

您的应用程序中的其他地方存在导致堆栈损坏的错误。尝试在 valgrind 下运行您的应用程序,或使用 -fsanitize=address 构建。任何一种方法都可以查明错误的确切位置,您应该能够据此找出问题所在。

【讨论】:

  • 为什么不呢?这很有意义,mmap 分配可以堆栈的内存,直到它真正命中它......(不过我会尝试你提供的......谢谢!)
  • @ZENir:因为,正如您自己引用的文档所说,“此标志当前是空操作”,这意味着它没有任何效果。 “检测到堆栈粉碎”通常意味着某些代码已超出堆栈分配的变量。
  • 哦,我认为 "no op" 部分意味着这是默认行为...
  • 嘿只是想更新导致堆栈崩溃的错误。我有一个pthread_t 数组,并且存在一个越界漏洞 - 意味着分配新线程的循环分配的线程多于数组的索引,并且在某些时候它溢出了 - 循环分配了具有索引的新线程变量实际上是堆栈cookie或其他东西。
【解决方案2】:

是否可以将 pthread_create 调用配置为不这样做?

pthread_create() 需要为线程的堆栈分配空间,否则线程无法运行——即使使用空线程函数也不行。这就是您看到的mmap 的用途。没有是不可能的。

或者可能使用 brk 或其他东西来自动增加数据段?

如果您有时间和技能来编写自己的线程库,那么请尝试告诉我们会发生什么。否则,不,pthread_create() 如何为新线程的堆栈保留空间的详细信息在我知道的任何实现中都是不可配置的。

无论如何这都无关紧要,因为mmap() 调用不是问题所在。如果系统调用出现不可恢复的故障,那么这是内核故障,您会得到内核恐慌,而不是应用程序崩溃。 GNU C 的堆栈粉碎检测发生在用户空间。因此,它所应用的函数不会出现在您的 strace 输出中,它仅跟踪 系统调用

这可能对您更好地了解堆栈粉碎和 GNU 的防御措施很有用。多布博士几年前跑过a nice article on just that,现在仍然值得一读。然而,最重要的是,当函数实现通过覆盖包含其返回地址的堆栈帧部分而行为不端时,就会发生堆栈粉碎。除非您正在进行一些内联​​汇编,否则几乎可以肯定,粉碎是由您自己的函数之一超出其局部变量之一的界限引起的。当该函数试图返回时,它会被检测到,方法是在服务于该目的的函数尾声中使用工具。

【讨论】:

  • 我宁愿引用原始的smashing the stack for fun and profit,但谢谢。无论如何,您确实回答了我关于配置pthread_create 的问题,而且我不打算编写自己的线程库o 现在代码重用发生了什么?! (开玩笑)。我将尝试在我的其余代码中查找缓冲区溢出。
猜你喜欢
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
相关资源
最近更新 更多