Skip to content

Commit afaf683

Browse files
Julien ThierryRussell King
authored andcommitted
ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization
Introduce C and asm helpers to sanitize user address, taking the address range they target into account. Use asm helper for existing sanitization in __copy_from_user(). Signed-off-by: Julien Thierry <julien.thierry@arm.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
1 parent e3aa624 commit afaf683

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

arch/arm/include/asm/assembler.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,17 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
467467
#endif
468468
.endm
469469

470+
.macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
471+
#ifdef CONFIG_CPU_SPECTRE
472+
sub \tmp, \limit, #1
473+
subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr
474+
addhs \tmp, \tmp, #1 @ if (tmp >= 0) {
475+
subhss \tmp, \tmp, \size @ tmp = limit - (addr + size) }
476+
movlo \addr, #0 @ if (tmp < 0) addr = NULL
477+
csdb
478+
#endif
479+
.endm
480+
470481
.macro uaccess_disable, tmp, isb=1
471482
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
472483
/*

arch/arm/include/asm/uaccess.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,32 @@ static inline void set_fs(mm_segment_t fs)
9999
#define __inttype(x) \
100100
__typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
101101

102+
/*
103+
* Sanitise a uaccess pointer such that it becomes NULL if addr+size
104+
* is above the current addr_limit.
105+
*/
106+
#define uaccess_mask_range_ptr(ptr, size) \
107+
((__typeof__(ptr))__uaccess_mask_range_ptr(ptr, size))
108+
static inline void __user *__uaccess_mask_range_ptr(const void __user *ptr,
109+
size_t size)
110+
{
111+
void __user *safe_ptr = (void __user *)ptr;
112+
unsigned long tmp;
113+
114+
asm volatile(
115+
" sub %1, %3, #1\n"
116+
" subs %1, %1, %0\n"
117+
" addhs %1, %1, #1\n"
118+
" subhss %1, %1, %2\n"
119+
" movlo %0, #0\n"
120+
: "+r" (safe_ptr), "=&r" (tmp)
121+
: "r" (size), "r" (current_thread_info()->addr_limit)
122+
: "cc");
123+
124+
csdb();
125+
return safe_ptr;
126+
}
127+
102128
/*
103129
* Single-value transfer routines. They automatically use the right
104130
* size if we just have the right pointer type. Note that the functions

arch/arm/lib/copy_from_user.S

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,7 @@ ENTRY(arm_copy_from_user)
9393
#ifdef CONFIG_CPU_SPECTRE
9494
get_thread_info r3
9595
ldr r3, [r3, #TI_ADDR_LIMIT]
96-
adds ip, r1, r2 @ ip=addr+size
97-
sub r3, r3, #1 @ addr_limit - 1
98-
cmpcc ip, r3 @ if (addr+size > addr_limit - 1)
99-
movcs r1, #0 @ addr = NULL
100-
csdb
96+
uaccess_mask_range_ptr r1, r2, r3, ip
10197
#endif
10298

10399
#include "copy_template.S"

0 commit comments

Comments
 (0)