hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/arch/arm/include/asm/uaccess.h
....@@ -1,9 +1,6 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * arch/arm/include/asm/uaccess.h
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
74 */
85 #ifndef _ASMARM_UACCESS_H
96 #define _ASMARM_UACCESS_H
....@@ -25,7 +22,7 @@
2522 * perform such accesses (eg, via list poison values) which could then
2623 * be exploited for priviledge escalation.
2724 */
28
-static inline unsigned int uaccess_save_and_enable(void)
25
+static __always_inline unsigned int uaccess_save_and_enable(void)
2926 {
3027 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
3128 unsigned int old_domain = get_domain();
....@@ -40,7 +37,7 @@
4037 #endif
4138 }
4239
43
-static inline void uaccess_restore(unsigned int flags)
40
+static __always_inline void uaccess_restore(unsigned int flags)
4441 {
4542 #ifdef CONFIG_CPU_SW_DOMAIN_PAN
4643 /* Restore the user access mask */
....@@ -59,7 +56,6 @@
5956 * Note that this is actually 0x1,0000,0000
6057 */
6158 #define KERNEL_DS 0x00000000
62
-#define get_ds() (KERNEL_DS)
6359
6460 #ifdef CONFIG_MMU
6561
....@@ -80,13 +76,18 @@
8076 modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
8177 }
8278
83
-#define segment_eq(a, b) ((a) == (b))
79
+#define uaccess_kernel() (get_fs() == KERNEL_DS)
8480
85
-/* We use 33-bit arithmetic here... */
81
+/*
82
+ * We use 33-bit arithmetic here. Success returns zero, failure returns
83
+ * addr_limit. We take advantage that addr_limit will be zero for KERNEL_DS,
84
+ * so this will always return success in that case.
85
+ */
8686 #define __range_ok(addr, size) ({ \
8787 unsigned long flag, roksum; \
8888 __chk_user_ptr(addr); \
89
- __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
89
+ __asm__(".syntax unified\n" \
90
+ "adds %1, %2, %3; sbcscc %1, %1, %0; movcc %0, #0" \
9091 : "=&r" (flag), "=&r" (roksum) \
9192 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
9293 : "cc"); \
....@@ -112,10 +113,11 @@
112113 unsigned long tmp;
113114
114115 asm volatile(
116
+ " .syntax unified\n"
115117 " sub %1, %3, #1\n"
116118 " subs %1, %1, %0\n"
117119 " addhs %1, %1, #1\n"
118
- " subhss %1, %1, %2\n"
120
+ " subshs %1, %1, %2\n"
119121 " movlo %0, #0\n"
120122 : "+r" (safe_ptr), "=&r" (tmp)
121123 : "r" (size), "r" (current_thread_info()->addr_limit)
....@@ -198,6 +200,7 @@
198200 register unsigned long __l asm("r1") = __limit; \
199201 register int __e asm("r0"); \
200202 unsigned int __ua_flags = uaccess_save_and_enable(); \
203
+ int __tmp_e; \
201204 switch (sizeof(*(__p))) { \
202205 case 1: \
203206 if (sizeof((x)) >= 8) \
....@@ -225,9 +228,10 @@
225228 break; \
226229 default: __e = __get_user_bad(); break; \
227230 } \
231
+ __tmp_e = __e; \
228232 uaccess_restore(__ua_flags); \
229233 x = (typeof(*(p))) __r2; \
230
- __e; \
234
+ __tmp_e; \
231235 })
232236
233237 #define get_user(x, p) \
....@@ -265,7 +269,7 @@
265269 */
266270 #define USER_DS KERNEL_DS
267271
268
-#define segment_eq(a, b) (1)
272
+#define uaccess_kernel() (true)
269273 #define __addr_ok(addr) ((void)(addr), 1)
270274 #define __range_ok(addr, size) ((void)(addr), 0)
271275 #define get_fs() (KERNEL_DS)
....@@ -279,7 +283,7 @@
279283
280284 #endif /* CONFIG_MMU */
281285
282
-#define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
286
+#define access_ok(addr, size) (__range_ok(addr, size) == 0)
283287
284288 #define user_addr_max() \
285289 (uaccess_kernel() ? ~0UL : get_fs())
....@@ -578,7 +582,7 @@
578582
579583 static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
580584 {
581
- if (access_ok(VERIFY_WRITE, to, n))
585
+ if (access_ok(to, n))
582586 n = __clear_user(to, n);
583587 return n;
584588 }