Add user pointer masking to __put_user() to mitigate Spectre v1. A write in a mispredicted access_ok() branch to a user-controlled kernel address can populate the rest of the affected cache line with kernel data.
This makes its behavior identical to put_user(), so converge their implementations. Signed-off-by: Josh Poimboeuf <jpoim...@kernel.org> --- arch/x86/lib/putuser.S | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S index cb137e0286be..1b122261b7aa 100644 --- a/arch/x86/lib/putuser.S +++ b/arch/x86/lib/putuser.S @@ -87,7 +87,26 @@ SYM_FUNC_START(__put_user_8) SYM_FUNC_END(__put_user_8) EXPORT_SYMBOL(__put_user_8) -/* .. and the same for __put_user, just without the range checks */ +#ifdef CONFIG_X86_64 + +/* + * On x86-64, put_user() does address masking rather than a conditional + * bounds check so there's no functional difference with __put_user(). + */ +SYM_FUNC_ALIAS(__put_user_nocheck_1, __put_user_1); +EXPORT_SYMBOL(__put_user_nocheck_1); + +SYM_FUNC_ALIAS(__put_user_nocheck_2, __put_user_2); +EXPORT_SYMBOL(__put_user_nocheck_2); + +SYM_FUNC_ALIAS(__put_user_nocheck_4, __put_user_4); +EXPORT_SYMBOL(__put_user_nocheck_4); + +SYM_FUNC_ALIAS(__put_user_nocheck_8, __put_user_8); +EXPORT_SYMBOL(__put_user_nocheck_8); + +#else /* CONFIG_X86_32 */ + SYM_FUNC_START(__put_user_nocheck_1) ASM_STAC 6: movb %al,(%_ASM_CX) @@ -118,15 +137,15 @@ EXPORT_SYMBOL(__put_user_nocheck_4) SYM_FUNC_START(__put_user_nocheck_8) ASM_STAC 9: mov %_ASM_AX,(%_ASM_CX) -#ifdef CONFIG_X86_32 10: movl %edx,4(%_ASM_CX) -#endif xor %ecx,%ecx ASM_CLAC RET SYM_FUNC_END(__put_user_nocheck_8) EXPORT_SYMBOL(__put_user_nocheck_8) +#endif /* CONFIG_X86_32 */ + SYM_CODE_START_LOCAL(__put_user_handle_exception) ASM_CLAC .Lbad_put_user: @@ -140,11 +159,9 @@ SYM_CODE_END(__put_user_handle_exception) _ASM_EXTABLE_UA(4b, __put_user_handle_exception) #ifdef CONFIG_X86_32 _ASM_EXTABLE_UA(5b, __put_user_handle_exception) -#endif _ASM_EXTABLE_UA(6b, __put_user_handle_exception) _ASM_EXTABLE_UA(7b, __put_user_handle_exception) _ASM_EXTABLE_UA(8b, __put_user_handle_exception) _ASM_EXTABLE_UA(9b, __put_user_handle_exception) -#ifdef CONFIG_X86_32 _ASM_EXTABLE_UA(10b, __put_user_handle_exception) #endif -- 2.47.0