Why does the Linux Kernel copy implementation use the AC flag?
Asked Answered
I

1

5

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?

Intersidereal answered 7/3, 2020 at 15:10 Comment(3)
Interesting. I always thought the AC flag had no effect to code runninig in ring 0 anyway.Fatidic
@Fatidic it has a new interpretation under SMAPLapidary
@harold Cool! I didn't know about that before.Fatidic
W
8

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.

Wainscot answered 7/3, 2020 at 15:52 Comment(2)
If not doing stac will it ends up in kernel panic?Intersidereal
@SomeName It probably won't cause a kernel panic, at least not directly. The code is designed to catch page fault exceptions. The _ASM_EXTABLE_UA(1b, 12b) line in the kernel source code creates an exception table entry for the REP MOVSB instruction (at label 1:) that causes the code at label 12: to be executed if that instruction causes a page fault. If AC is clear then executing REP MOVSB should fault on the first memory access and the copy_user_enhanced_fast_string function would return 0, indicating that 0 bytes had been copied. This may end up causing the kernel to panic.Wainscot

© 2022 - 2024 — McMap. All rights reserved.