The implementation of copy_user_enhanced_fast_string
in the Linux Kernel copy routine uses stac
/clac
in the epilog and prolog. perf annotate
shows the following code:
stac cmp $0x40,%edx jb 0xffffffff91281f5c mov %edx,%ecx rep movsb %ds:(%rsi),%es:(%rdi) xor %eax,%eax clac retq
AC
is “Alignment check (or access control) flag”.
What is the reason stac
/clac
are used in the routine? What would be the consequences if we simply remove them?
Advertisement
Answer
Normally all page access checks are disabled in supervisor-mode and the kernel can read or write to any page regardless of whether its read-only or marked as a supervisor or user page. However if Supervisor-Mode Access Protection is enabled (CR4.SMAP = 1), then the AC flag controls whether the kernel can read or write user-mode pages. If EFLAGS.AC is 0 then reading or writing to user-mode pages will cause a page-fault exception. If EFLAGS.AC is 1 then kernel is permitted to read and write user mode pages.
The STAC and CLAC instructions were invented to allow quick and easy changing of the AC flag in code like in your example. By setting EFLAGS.AC the REP MOVSB instruction is allowed to access user-mode pages. By clearing EFLAGS.AC at the end, the kernel is once again protected against accidental user-mode accesses that could be exploited by malicious code.