Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stuart MENEFY and committed by
Paul Mundt
5d52013c 2cd0ebc8

+8 -3
+8 -3
arch/sh/lib/copy_page.S
··· 80 80 .section __ex_table, "a"; \ 81 81 .long 9999b, 6000f ; \ 82 82 .previous 83 + #define EX_NO_POP(...) \ 84 + 9999: __VA_ARGS__ ; \ 85 + .section __ex_table, "a"; \ 86 + .long 9999b, 6005f ; \ 87 + .previous 83 88 ENTRY(__copy_user) 84 89 ! Check if small number of bytes 85 90 mov #11,r0 ··· 144 139 bt 1f 145 140 146 141 2: 147 - EX( mov.b @r5+,r0 ) 142 + EX_NO_POP( mov.b @r5+,r0 ) 148 143 dt r6 149 - EX( mov.b r0,@r4 ) 144 + EX_NO_POP( mov.b r0,@r4 ) 150 145 bf/s 2b 151 146 add #1,r4 152 147 ··· 155 150 156 151 # Exception handler: 157 152 .section .fixup, "ax" 158 - 6000: 153 + 6005: 159 154 mov.l 8000f,r1 160 155 mov r3,r0 161 156 jmp @r1