Seccomp:为什么下面的程序会死锁?

Seccomp: Why does the following program deadlock?

我有简单的测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <pthread.h>

#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <sys/syscall.h>

void *do_work(void *args) {
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
    printf("OK.\n");
}

int main() {
    pthread_t t;
    int ret;
    ret = pthread_create(&t, NULL, do_work, NULL);
    if (ret != 0) {
        printf("Could not create thread, error is %d.\n", ret);
        return 1;
    }
    ret = pthread_join(t, NULL);
    if (ret != 0) {
        printf("Could not join thread, error is %d.\n", ret);
        return 2;
    }
    printf("Program done.\n");
    return 0;
}

在 Ubuntu 16.04 中,此死锁没有打印任何内容。通过阅读有关 seccomp 的文档,我不清楚为什么会发生这种情况。为什么呢? SIGKILL 不会杀死整个进程吗?

原因是 printf 函数。

如果您在程序中 运行 strace -f(没有 prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); 行),您将看到创建的线程调用 futex 系统调用。

调用futexseccomp模式禁止,所以线程被杀死,所以pthread_join无限等待。

如果将 printf() 替换为 write(1,...),程序将按预期运行。

创建的线程与原始线程具有不同的进程 ID(根据 strace)。因此,只有新线程在违反 seccomp 时才会被杀死。这意味着死锁。