diff options
| author | Stuart MENEFY <stuart.menefy@st.com> | 2008-10-10 14:49:30 -0400 | 
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2008-11-13 03:40:30 -0500 | 
| commit | 5d52013cbb3d39bde9f5a6023193058eeb112e98 (patch) | |
| tree | e941d9e884132d72c002536955014a938d740906 | |
| parent | 2cd0ebc83d771220eeddec91fd6d4cfefc2cc46e (diff) | |
sh: __copy_user function can corrupt the stack in case of exception
The __copy_user function can corrupt the stack in the case of a
non-trivial length of data, and either of the first two move instructions
cause an exception. This is because the fixup for these two instructions
is mapped to the no_pop case, but these instructions execute after the
stack is pushed.
This change creates an explicit NO_POP exception mapping macro, and uses
it for the two instructions executed in the trivial case where no stack
pushes occur.
More information at ST Linux bugzilla:
	https://bugzilla.stlinux.com/show_bug.cgi?id=4824
Signed-off-by: Dylan Reid <dylan_reid@bose.com>
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
| -rw-r--r-- | arch/sh/lib/copy_page.S | 11 | 
1 files changed, 8 insertions, 3 deletions
| diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S index 5d12e657be34..43de7e8e4e17 100644 --- a/arch/sh/lib/copy_page.S +++ b/arch/sh/lib/copy_page.S | |||
| @@ -80,6 +80,11 @@ ENTRY(copy_page) | |||
| 80 | .section __ex_table, "a"; \ | 80 | .section __ex_table, "a"; \ | 
| 81 | .long 9999b, 6000f ; \ | 81 | .long 9999b, 6000f ; \ | 
| 82 | .previous | 82 | .previous | 
| 83 | #define EX_NO_POP(...) \ | ||
| 84 | 9999: __VA_ARGS__ ; \ | ||
| 85 | .section __ex_table, "a"; \ | ||
| 86 | .long 9999b, 6005f ; \ | ||
| 87 | .previous | ||
| 83 | ENTRY(__copy_user) | 88 | ENTRY(__copy_user) | 
| 84 | ! Check if small number of bytes | 89 | ! Check if small number of bytes | 
| 85 | mov #11,r0 | 90 | mov #11,r0 | 
| @@ -139,9 +144,9 @@ EX( mov.b r1,@r4 ) | |||
| 139 | bt 1f | 144 | bt 1f | 
| 140 | 145 | ||
| 141 | 2: | 146 | 2: | 
| 142 | EX( mov.b @r5+,r0 ) | 147 | EX_NO_POP( mov.b @r5+,r0 ) | 
| 143 | dt r6 | 148 | dt r6 | 
| 144 | EX( mov.b r0,@r4 ) | 149 | EX_NO_POP( mov.b r0,@r4 ) | 
| 145 | bf/s 2b | 150 | bf/s 2b | 
| 146 | add #1,r4 | 151 | add #1,r4 | 
| 147 | 152 | ||
| @@ -150,7 +155,7 @@ EX( mov.b r0,@r4 ) | |||
| 150 | 155 | ||
| 151 | # Exception handler: | 156 | # Exception handler: | 
| 152 | .section .fixup, "ax" | 157 | .section .fixup, "ax" | 
| 153 | 6000: | 158 | 6005: | 
| 154 | mov.l 8000f,r1 | 159 | mov.l 8000f,r1 | 
| 155 | mov r3,r0 | 160 | mov r3,r0 | 
| 156 | jmp @r1 | 161 | jmp @r1 | 
