The tags must not be included into check whether it's okay to access the userspace address. __chk_range_not_ok() is at the core or access_ok() and it's handly to strip tags there. get_user() and put_user() don't use access_ok(), but check access against TASK_SIZE direcly in assembly. Strip tags, before calling into the assembly helper. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- arch/x86/include/asm/uaccess.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index c9fa7be3df82..ee0a482b2f1f 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -18,6 +18,9 @@ */ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit) { + /* Remove tags from the address before comparing to the limit */ + addr = untagged_addr(addr); + /* * If we have used "sizeof()" for the size, * we know it won't overflow the limit (but @@ -152,7 +155,12 @@ extern int __get_user_bad(void); * Return: zero on success, or -EFAULT on error. * On error, the variable @x is set to zero. */ -#define get_user(x,ptr) ({ might_fault(); do_get_user_call(get_user,x,ptr); }) +#define get_user(x,ptr) \ +({ \ + __typeof__(*(ptr)) *__ptr_clean = untagged_ptr(ptr); \ + might_fault(); \ + do_get_user_call(get_user,x,__ptr_clean); \ +}) /** * __get_user - Get a simple variable from user space, with less checking. @@ -249,7 +257,11 @@ extern void __put_user_nocheck_8(void); * * Return: zero on success, or -EFAULT on error. */ -#define put_user(x, ptr) ({ might_fault(); do_put_user_call(put_user,x,ptr); }) +#define put_user(x, ptr) ({ \ + __typeof__(*(ptr)) *__ptr_clean = untagged_ptr(ptr); \ + might_fault(); \ + do_put_user_call(put_user,x,__ptr_clean); \ +}) /** * __put_user - Write a simple value into user space, with less checking. -- 2.26.2