我在 ARM v6/v7 平台上验证 XN 位的硬件支持。为此,我在 ARM 上执行了 execstack.c。由于 ARM v6/v7 支持 XN 位,因此它正在崩溃。然后我在不支持 XI 位的 MIPS 目标(34Kc)上检查了相同的内容,因此程序必须正常执行,但这里程序也崩溃了。然后我删除了 XN 位代码并为 ARM 编译。然后程序也崩溃了,这不应该。
Test Program /* execstack.c - 测试栈上的代码是否可以执行
*/
typedef void (*fptr)(void);
char *testname = "Executable stack ";
void itworked( void )
{
printf( "Vulnerable\n" );
exit( 1 );
}
void doit( void )
{
char buf[8192];
fptr func;
/* Put a RETN instruction in the buffer */
buf[0] = '\xc3';
/* Convert the pointer to a function pointer */
func = (fptr)buf;
/* Call the code in the buffer */
func();
/* It worked when the function returns */
itworked();
}
int main( int argc, char *argv[] )
{
int status;
printf( "%s: ", testname );
fflush( stdout );
if( fork() == 0 ) {
do_mprotect((unsigned long)argv & ~4095U, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
doit();
} else {
wait( &status );
if( WIFEXITED(status) == 0 ) {
printf( "Killed\n" );
exit( 0 );
}
}
exit( 0 );
}
void itfailed( void )
{
printf( "Ok\n" );
exit( 2 );
}
int do_mprotect( const void *addr, size_t len, int prot )
{
void *ptr;
int retval;
/* Allign to a multiple of PAGESIZE, assumed to be a power of two */
ptr = (char *)(((unsigned long) addr) & ~(PAGESIZE-1));
retval = mprotect( ptr, len, prot );
if( retval != 0 && errno == EINVAL ) {
perror( "could not mprotect():" );
exit( 1 );
}
return retval;
}
/登录 MIPS 目标 /
在 MIPS 目标上,execstack 测试用例在 coredump 下方给出,尽管我假设 MIPS 不支持 XI 位。
VDLinux#> ./execstack
可执行堆栈[53.272000] do_ri() : 发送 SIGILL 到 execstack, PID:386
被杀
/登录ARM目标/
VDLinux#> ./execstack
可执行堆栈[451.784000] execstack:0xbead5860 处未处理的页面错误 (11),代码 0x80000007 被杀死
所以我有以下问题:
- 如何验证 ARM v6/V7 上的 XN 位支持?
- 如何验证 MIPS 34Kc 上的 XI 位支持
- 在哪里可以检查 Linux 内核代码中的 XN 位支持。
谢谢, 吉里什