Mac M1 在另一个上“cp”二进制文件会导致崩溃

jya*_*yne 9 binary macos apple-m1

最近,我一直在观察在将一个二进制文件复制到另一个二进制文件上而没有先在我的 M1 上删除它后发生的问题。经过一些实验(在遇到这个问题之后),我想出了一种可重现的方法,可以在最新的 11.3 版 Big Sur 的 Apple 新硬件上解决这个问题。

当在至少运行一次后将不同的二进制文件复制到另一个二进制文件时,就会出现此问题。不确定是什么导致了这个问题,但它非常令人困惑,并且可能会导致一些安全问题。

例如,这会产生错误:

> ./binaryA
# output A
> ./binaryB
# output B
> cp binaryA binaryB
> ./binaryB
Killed: 9 
Run Code Online (Sandbox Code Playgroud)

设置

为了重现上述行为,我们可以创建两个简单的 C 文件,其中包含以下内容:

// binaryA.c
#include<stdio.h>

int main() {
    printf("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)
// binaryB.c
#include<stdio.h>
const char s[] = "Hello world 123!"; // to make sizes differ for clarity

int main() {
    printf("%s", s);
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以运行以下命令并获取描述的错误(必须运行程序才能重现问题,因此运行以下程序是必要的):

> gcc -o binaryA binaryA.c
> gcc -o binaryB binaryB.c
> ./binaryA
Hello world!
> ./binaryB
Hello world 123!
> cp binaryA binaryB
> ./binaryB
Killed: 9
Run Code Online (Sandbox Code Playgroud)

如您所见,binaryB二进制文件不再有效。出于所有意图和目的,这两个二进制文件是相同的,但一个可以运行,另一个不能运行。两个二进制文件的Adiff均不返回任何内容。

我假设这是某种签名问题?但这不应该是因为两个二进制文件无论如何都没有签名。

有没有人有这种行为背后的理论或者这是一个错误?另外,如果这是一个错误,我该将其归档到哪里?

Tre*_*rev 5

每当更新签名文件时,都需要创建一个新文件。

具体来说,代码签名信息(代码目录哈希)挂在内核内的 vnode 上,修改该缓存后面的文件将导致问题。你需要一个新的vnode,这意味着一个新的文件,也就是一个新的inode。记录于 WWDC 2019 会议 703 关于公证的一切 - 请参阅幻灯片 65。

这是因为 ARM M1 处理器上的 Big Sur 要求所有代码都经过有效签名(如果只是临时的),否则操作系统将不会执行它,而是在启动时杀死它。