如何在 Mac 上使用 Intel 的内存保护扩展 (MPX) 编译程序?
How can I compile a program with Intel's Memory Protection Extensions (MPX) on a Mac?
我正在尝试通过镜像 this tutorial for Linux 在我的 Macbook Pro 上测试英特尔的内存保护扩展 (MPX)。我的处理器是 Intel Core i5-6267U,它确实有能力使用 MPX,经 运行 sysctl machdep.cpu | grep MPX
验证。但是,当我尝试编译以下测试程序时:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define noinline __attribute__((noinline))
char dog[] = "dog";
char password[] = "secr3t";
noinline
char dog_letter(int nr)
{
return dog[nr];
}
int main(int argc, char **argv)
{
int max = sizeof(dog);
int i;
if (argc >= 2)
max = atoi(argv[1]);
for (i = 0; i < max; i++)
printf("dog[%d]: '%c'\n", i, dog_letter(i));
return 0;
}
使用以下命令:
/usr/local/bin/gcc-8 -o mpx_test -fcheck-pointer-bounds -mmpx mpx_test.c
我收到以下错误字符串:
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:26:10: error: unexpected token in argument list
bnd jle L2
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:37:11: error: unexpected token in argument list
bnd call _atoi
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:41:10: error: unexpected token in argument list
bnd jmp L3
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:45:11: error: unexpected token in argument list
bnd call _dog_letter
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:57:9: error: unexpected token in argument list
bnd jl L4
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:61:2: error: invalid instruction mnemonic 'bnd'
bnd ret
^~~
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:88:2: error: invalid instruction mnemonic 'bnd'
bnd ret
^~~
如果我使用 -S 标志进行编译,我可以看到 GCC 生成的程序集确实具有 MPX 特定指令 (bnd...
)。我还需要做什么来编译带有 MPX 保护的程序?
我找到了一种解决方法,可以让我在我的 Mac 上使用 MPX - 虽然它实际上只适用于小程序。我为 kernel space 使 MPX 工作所采取的步骤如下:
- 启用 MPX。有关如何执行此操作的信息,请参阅 Intel 手册。简而言之,需要向 MSR 写入一些位。
- 启动 Linux VM 或跳到具有支持 MPX 的 assembler 的任何其他系统。
- 在第二个系统上,写出 MPX 汇编指令(您想要的程序返回 Mac)和 assemble 程序。
- Disassemble 通过
objdump -d
程序并将相关 MPX 指令和操作数的操作码复制到 Mac. 上的内联汇编中
- 在 Mac 上编译和 运行 :)
这也适用于用户 space 中的 MPX,但对启用 MPX 的方式略有更改(XSAVE
用户 space 的说明和内核 [=40= 的 MSR ]).
作为复制操作码后 Mac 上的内联汇编的示例,请考虑以下内容。
__asm__ volatile (
".byte 0xf3, 0x0f, 0x1b, 0x40, 0x10 \t\n" // bndmk 16(%rax), %bnd0
".byte 0xf2, 0x0f, 0x1a, 0x40, 0x16 \t\n" // bndcu 22(%rax), %bnd0
:
: "a" (some_input)
);
我正在尝试通过镜像 this tutorial for Linux 在我的 Macbook Pro 上测试英特尔的内存保护扩展 (MPX)。我的处理器是 Intel Core i5-6267U,它确实有能力使用 MPX,经 运行 sysctl machdep.cpu | grep MPX
验证。但是,当我尝试编译以下测试程序时:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define noinline __attribute__((noinline))
char dog[] = "dog";
char password[] = "secr3t";
noinline
char dog_letter(int nr)
{
return dog[nr];
}
int main(int argc, char **argv)
{
int max = sizeof(dog);
int i;
if (argc >= 2)
max = atoi(argv[1]);
for (i = 0; i < max; i++)
printf("dog[%d]: '%c'\n", i, dog_letter(i));
return 0;
}
使用以下命令:
/usr/local/bin/gcc-8 -o mpx_test -fcheck-pointer-bounds -mmpx mpx_test.c
我收到以下错误字符串:
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:26:10: error: unexpected token in argument list
bnd jle L2
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:37:11: error: unexpected token in argument list
bnd call _atoi
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:41:10: error: unexpected token in argument list
bnd jmp L3
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:45:11: error: unexpected token in argument list
bnd call _dog_letter
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:57:9: error: unexpected token in argument list
bnd jl L4
^
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:61:2: error: invalid instruction mnemonic 'bnd'
bnd ret
^~~
/var/folders/v0/g_jfwt1j0kj1cp6vjn818jjh0000gn/T//cc5F0fho.s:88:2: error: invalid instruction mnemonic 'bnd'
bnd ret
^~~
如果我使用 -S 标志进行编译,我可以看到 GCC 生成的程序集确实具有 MPX 特定指令 (bnd...
)。我还需要做什么来编译带有 MPX 保护的程序?
我找到了一种解决方法,可以让我在我的 Mac 上使用 MPX - 虽然它实际上只适用于小程序。我为 kernel space 使 MPX 工作所采取的步骤如下:
- 启用 MPX。有关如何执行此操作的信息,请参阅 Intel 手册。简而言之,需要向 MSR 写入一些位。
- 启动 Linux VM 或跳到具有支持 MPX 的 assembler 的任何其他系统。
- 在第二个系统上,写出 MPX 汇编指令(您想要的程序返回 Mac)和 assemble 程序。
- Disassemble 通过
objdump -d
程序并将相关 MPX 指令和操作数的操作码复制到 Mac. 上的内联汇编中
- 在 Mac 上编译和 运行 :)
这也适用于用户 space 中的 MPX,但对启用 MPX 的方式略有更改(XSAVE
用户 space 的说明和内核 [=40= 的 MSR ]).
作为复制操作码后 Mac 上的内联汇编的示例,请考虑以下内容。
__asm__ volatile (
".byte 0xf3, 0x0f, 0x1b, 0x40, 0x10 \t\n" // bndmk 16(%rax), %bnd0
".byte 0xf2, 0x0f, 0x1a, 0x40, 0x16 \t\n" // bndcu 22(%rax), %bnd0
:
: "a" (some_input)
);