diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2019-03-01 14:19:06 +0000 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2019-03-01 14:19:06 +0000 |
commit | 3cd0ddb3deec43bd1cfcdd39d3dde37a0135d0c6 (patch) | |
tree | d3a822c98c06f0e5c4481e8900baf827d287598f | |
parent | 366e37e4da23f9df498cc9577cadcb354f7bd431 (diff) | |
download | linux-3cd0ddb3deec43bd1cfcdd39d3dde37a0135d0c6.tar.bz2 |
Revert "arm64: uaccess: Implement unsafe accessors"
This reverts commit 0bd3ef34d2a8dd4056560567073d8bfc5da92e39.
There is ongoing work on objtool to identify incorrect uses of
user_access_{begin,end}. Until this is sorted, do not enable the
functionality on arm64. Also, on ARMv8.2 CPUs with hardware PAN and UAO
support, there is no obvious performance benefit to the unsafe user
accessors.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/include/asm/uaccess.h | 79 |
1 files changed, 20 insertions, 59 deletions
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 6a70c75ed9f4..8e408084b8c3 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -270,26 +270,31 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr) #define __raw_get_user(x, ptr, err) \ do { \ + unsigned long __gu_val; \ + __chk_user_ptr(ptr); \ + uaccess_enable_not_uao(); \ switch (sizeof(*(ptr))) { \ case 1: \ - __get_user_asm("ldrb", "ldtrb", "%w", (x), (ptr), \ + __get_user_asm("ldrb", "ldtrb", "%w", __gu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 2: \ - __get_user_asm("ldrh", "ldtrh", "%w", (x), (ptr), \ + __get_user_asm("ldrh", "ldtrh", "%w", __gu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 4: \ - __get_user_asm("ldr", "ldtr", "%w", (x), (ptr), \ + __get_user_asm("ldr", "ldtr", "%w", __gu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 8: \ - __get_user_asm("ldr", "ldtr", "%x", (x), (ptr), \ + __get_user_asm("ldr", "ldtr", "%x", __gu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ default: \ BUILD_BUG(); \ } \ + uaccess_disable_not_uao(); \ + (x) = (__force __typeof__(*(ptr)))__gu_val; \ } while (0) #define __get_user_error(x, ptr, err) \ @@ -297,13 +302,8 @@ do { \ __typeof__(*(ptr)) __user *__p = (ptr); \ might_fault(); \ if (access_ok(__p, sizeof(*__p))) { \ - unsigned long __gu_val; \ - __chk_user_ptr(__p); \ __p = uaccess_mask_ptr(__p); \ - uaccess_enable_not_uao(); \ - __raw_get_user(__gu_val, __p, (err)); \ - uaccess_disable_not_uao(); \ - (x) = (__force __typeof__(*__p)) __gu_val; \ + __raw_get_user((x), __p, (err)); \ } else { \ (x) = 0; (err) = -EFAULT; \ } \ @@ -334,26 +334,30 @@ do { \ #define __raw_put_user(x, ptr, err) \ do { \ + __typeof__(*(ptr)) __pu_val = (x); \ + __chk_user_ptr(ptr); \ + uaccess_enable_not_uao(); \ switch (sizeof(*(ptr))) { \ case 1: \ - __put_user_asm("strb", "sttrb", "%w", (x), (ptr), \ + __put_user_asm("strb", "sttrb", "%w", __pu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 2: \ - __put_user_asm("strh", "sttrh", "%w", (x), (ptr), \ + __put_user_asm("strh", "sttrh", "%w", __pu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 4: \ - __put_user_asm("str", "sttr", "%w", (x), (ptr), \ + __put_user_asm("str", "sttr", "%w", __pu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ case 8: \ - __put_user_asm("str", "sttr", "%x", (x), (ptr), \ + __put_user_asm("str", "sttr", "%x", __pu_val, (ptr), \ (err), ARM64_HAS_UAO); \ break; \ default: \ BUILD_BUG(); \ } \ + uaccess_disable_not_uao(); \ } while (0) #define __put_user_error(x, ptr, err) \ @@ -361,13 +365,9 @@ do { \ __typeof__(*(ptr)) __user *__p = (ptr); \ might_fault(); \ if (access_ok(__p, sizeof(*__p))) { \ - __typeof__(*(ptr)) __pu_val = (x); \ - __chk_user_ptr(__p); \ __p = uaccess_mask_ptr(__p); \ - uaccess_enable_not_uao(); \ - __raw_put_user(__pu_val, __p, (err)); \ - uaccess_disable_not_uao(); \ - } else { \ + __raw_put_user((x), __p, (err)); \ + } else { \ (err) = -EFAULT; \ } \ } while (0) @@ -381,45 +381,6 @@ do { \ #define put_user __put_user -static __must_check inline bool user_access_begin(const void __user *ptr, - size_t len) -{ - if (unlikely(!access_ok(ptr, len))) - return false; - - uaccess_enable_not_uao(); - return true; -} -#define user_access_begin(ptr, len) user_access_begin(ptr, len) -#define user_access_end() uaccess_disable_not_uao() - -#define unsafe_get_user(x, ptr, err) \ -do { \ - __typeof__(*(ptr)) __user *__p = (ptr); \ - unsigned long __gu_val; \ - int __gu_err = 0; \ - might_fault(); \ - __chk_user_ptr(__p); \ - __p = uaccess_mask_ptr(__p); \ - __raw_get_user(__gu_val, __p, __gu_err); \ - (x) = (__force __typeof__(*__p)) __gu_val; \ - if (__gu_err != 0) \ - goto err; \ -} while (0) - -#define unsafe_put_user(x, ptr, err) \ -do { \ - __typeof__(*(ptr)) __user *__p = (ptr); \ - __typeof__(*(ptr)) __pu_val = (x); \ - int __pu_err = 0; \ - might_fault(); \ - __chk_user_ptr(__p); \ - __p = uaccess_mask_ptr(__p); \ - __raw_put_user(__pu_val, __p, __pu_err); \ - if (__pu_err != 0) \ - goto err; \ -} while (0) - extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n); #define raw_copy_from_user(to, from, n) \ ({ \ |