The old smap_save() code was:
pushf pop %0
with %0 defined by an "=rm" constraint. This is fine if the compiler picked the register option, but it was incorrect with an %rsp-relative memory operand. With some intentional abuse, I can get both gcc and clang to generate code along these lines:
pushfq popq 0x8(%rsp) mov 0x8(%rsp),%rax
which is incorrect and will not work as intended.
Fix it by removing the memory option. This issue is exacerbated by a clang optimization bug:
https://bugs.llvm.org/show_bug.cgi?id=47530
Fixes: e74deb11931f ("x86/uaccess: Introduce user_access_{save,restore}()") Cc: stable@vger.kernel.org Reported-by: Bill Wendling morbo@google.com # I think Signed-off-by: Andy Lutomirski luto@kernel.org --- arch/x86/include/asm/smap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index 8b58d6975d5d..be6d675ae3ac 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h @@ -61,7 +61,7 @@ static __always_inline unsigned long smap_save(void) ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP) "pushf; pop %0; " __ASM_CLAC "\n\t" "1:" - : "=rm" (flags) : : "memory", "cc"); + : "=r" (flags) : : "memory", "cc");
return flags; }