Skip to content

Why does the Linux Kernel copy implementation use the AC flag?

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:

cmp  $0x40,%edx
jb   0xffffffff91281f5c
mov  %edx,%ecx
rep  movsb %ds:(%rsi),%es:(%rdi)
xor  %eax,%eax

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?



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.

5 People found this is helpful