aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-09-07 18:22:28 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-21 19:22:24 +0100
commitc59f723a562f9539dfac68c1b306858e35a05cdd (patch)
tree445aadf76dce4b88d1ad58e9b153b7737b210b33
parentbd826b68f05e721b8be8a8dbe8f556ed7eb4ae54 (diff)
downloadkernel_samsung_smdk4412-c59f723a562f9539dfac68c1b306858e35a05cdd.zip
kernel_samsung_smdk4412-c59f723a562f9539dfac68c1b306858e35a05cdd.tar.gz
kernel_samsung_smdk4412-c59f723a562f9539dfac68c1b306858e35a05cdd.tar.bz2
ARM: 7527/1: uaccess: explicitly check __user pointer when !CPU_USE_DOMAINS
The {get,put}_user macros don't perform range checking on the provided __user address when !CPU_HAS_DOMAINS. This patch reworks the out-of-line assembly accessors to check the user address against a specified limit, returning -EFAULT if is is out of range. [will: changed get_user register allocation to match put_user] [rmk: fixed building on older ARM architectures] CRs-Fixed: 504011 Reported-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Cc: stable@vger.kernel.org Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Git-commit: 8404663f81d212918ff85f493649a7991209fa04 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Laura Abbott <lauraa@codeaurora.org> Conflicts: arch/arm/include/asm/assembler.h arch/arm/lib/getuser.S arch/arm/lib/putuser.S Change-Id: I3818045a136fcdf72deb1371b132e090fd7ed643 Conflicts: arch/arm/lib/getuser.S arch/arm/lib/putuser.S
-rw-r--r--arch/arm/include/asm/assembler.h16
-rw-r--r--arch/arm/lib/copy_from_user.S9
-rw-r--r--arch/arm/lib/copy_template.S46
-rw-r--r--arch/arm/lib/copy_to_user.S9
-rw-r--r--arch/arm/lib/memcpy.S9
5 files changed, 72 insertions, 17 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 456649e..b7c5d5d 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -299,14 +299,6 @@
usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
- .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
-#ifndef CONFIG_CPU_USE_DOMAINS
- adds \tmp, \addr, #\size - 1
- sbcccs \tmp, \tmp, \limit
- bcs \bad
-#endif
- .endm
-
/* Utility macro for declaring string literals */
.macro string name:req, string
.type \name , #object
@@ -315,4 +307,12 @@
.size \name , . - \name
.endm
+ .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
+#ifndef CONFIG_CPU_USE_DOMAINS
+ adds \tmp, \addr, #\size - 1
+ sbcccs \tmp, \tmp, \limit
+ bcs \bad
+#endif
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 66a477a..54daeae 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -68,6 +68,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldr1w \src, \reg1, \abort
+ ldr1w \src, \reg2, \abort
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 805e3f8..f2b5885 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -66,6 +66,7 @@
* than one 32bit instruction in Thumb-2)
*/
+#define PLDSIZE (CONFIG_ARM_PLD_SIZE)
enter r4, lr
@@ -90,19 +91,46 @@
CALGN( add pc, r4, ip )
PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
+
+#if (PLDSIZE == 64)
+2: PLD( cmp r2, #32)
+ PLD( blt .32copy)
+
+.64copy:
+ PLD( subs r2, r2, #(PLDSIZE*3+32) )
+ PLD( pld [r1, #PLDSIZE-4] )
PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
+ PLD( pld [r1, #PLDSIZE*2-4] )
+ PLD( pld [r1, #PLDSIZE*3-4] )
+3: PLD( pld [r1, #PLDSIZE*4-4] )
+4: cpy8w r0, r1, r4, r5, abort=20f
+ cpy8w r0, r1, r4, r5, abort=20f
+ subs r2, r2, #PLDSIZE
+ bge 3b
+ PLD( cmn r2, #(PLDSIZE*3) )
+ PLD( bge 4b )
+
+ PLD( cmn r2, #(PLDSIZE*4-32) )
+ PLD( blt 5f)
+
+.32copy:
+ cpy8w r0, r1, r4, r5, abort=20f
+#else
+2: PLD( subs r2, r2, #(PLDSIZE*3) )
+ PLD( pld [r1, #(PLDSIZE-4)] )
+ PLD( blt 4f )
+ PLD( pld [r1, #(PLDSIZE*2-4)] )
+ PLD( pld [r1, #(PLDSIZE*3-4)] )
+
+3: PLD( pld [r1, #(PLDSIZE*4-4)] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #PLDSIZE
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
bge 3b
- PLD( cmn r2, #96 )
+ PLD( cmn r2, #(PLDSIZE*3) )
PLD( bge 4b )
+#endif
5: ands ip, r2, #28
rsb ip, ip, #32
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index d066df6..e32788b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -71,6 +71,15 @@
str1w \ptr, \reg8, \abort
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ str1w \dst, \reg1, \abort
+ str1w \dst, \reg2, \abort
+ .endr
+ add \src, \src, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index a9b9e22..7ffda59 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -40,6 +40,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \src, \src, #32
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm