Som*_*ame 4 linux x86 assembly linux-kernel systems-programming
执行copy_user_enhanced_fast_string在Linux内核复制常规用途stac/clac在收尾和序言。perf annotate显示以下代码:
stac
cmp $0x40,%edx
jb 0xffffffff91281f5c
mov %edx,%ecx
rep movsb %ds:(%rsi),%es:(%rdi)
xor %eax,%eax
clac
retq
Run Code Online (Sandbox Code Playgroud)
AC 是“对齐检查(或访问控制)标志”。
是什么原因stac/clac在例程中使用?如果我们简单地删除它们会产生什么后果?
通常,所有页面访问检查在主管模式下都是禁用的,内核可以读取或写入任何页面,无论其是只读页面还是标记为主管或用户页面。但是,如果启用了超级用户模式访问保护(CR4.SMAP = 1),则 AC 标志控制内核是否可以读取或写入用户模式页面。如果 EFLAGS.AC 为 0,则读取或写入用户模式页面将导致页面错误异常。如果 EFLAGS.AC 为 1,则允许内核读取和写入用户模式页面。
发明了 STAC 和 CLAC 指令以允许快速轻松地更改代码中的 AC 标志,例如您的示例。通过设置 EFLAGS.AC,允许 REP MOVSB 指令访问用户模式页面。通过最后清除 EFLAGS.AC,内核再次受到保护,防止可能被恶意代码利用的意外用户模式访问。