linux: remove 4.7.x kernel, default to 4.8.x
[openadk.git] / target / linux / patches / 4.4.20 / revert-sparc.patch
blob296be0e4afce70f9a9f5eced21989faec2b54273
1 From fff1ade5bd7576b053b6bbc9c9b72c2572092c06 Mon Sep 17 00:00:00 2001
2 From: Waldemar Brodkorb <wbx@uclibc-ng.org>
3 Date: Wed, 6 Jul 2016 08:16:59 +0200
4 Subject: [PATCH] Revert "sparc: Harden signal return frame checks."
6 This reverts commit 1fda90c39d8ef6acbedfd3cd9bd710a5bcc490c3.
8 Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
9 ---
10 arch/sparc/kernel/signal32.c | 46 ++++++++++++++--------------------------
11 arch/sparc/kernel/signal_32.c | 41 +++++++++++++----------------------
12 arch/sparc/kernel/signal_64.c | 31 ++++++++++-----------------
13 arch/sparc/kernel/sigutil_32.c | 9 +-------
14 arch/sparc/kernel/sigutil_64.c | 10 ++-------
15 5 files changed, 45 insertions(+), 92 deletions(-)
17 diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
18 index 77655f0..4eed773 100644
19 --- a/arch/sparc/kernel/signal32.c
20 +++ b/arch/sparc/kernel/signal32.c
21 @@ -138,24 +138,12 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
22 return 0;
25 -/* Checks if the fp is valid. We always build signal frames which are
26 - * 16-byte aligned, therefore we can always enforce that the restore
27 - * frame has that property as well.
28 - */
29 -static bool invalid_frame_pointer(void __user *fp, int fplen)
31 - if ((((unsigned long) fp) & 15) ||
32 - ((unsigned long)fp) > 0x100000000ULL - fplen)
33 - return true;
34 - return false;
37 void do_sigreturn32(struct pt_regs *regs)
39 struct signal_frame32 __user *sf;
40 compat_uptr_t fpu_save;
41 compat_uptr_t rwin_save;
42 - unsigned int psr, ufp;
43 + unsigned int psr;
44 unsigned pc, npc;
45 sigset_t set;
46 compat_sigset_t seta;
47 @@ -170,16 +158,11 @@ void do_sigreturn32(struct pt_regs *regs)
48 sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
50 /* 1. Make sure we are not getting garbage from the user */
51 - if (invalid_frame_pointer(sf, sizeof(*sf)))
52 - goto segv;
54 - if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
55 - goto segv;
57 - if (ufp & 0x7)
58 + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
59 + (((unsigned long) sf) & 3))
60 goto segv;
62 - if (__get_user(pc, &sf->info.si_regs.pc) ||
63 + if (get_user(pc, &sf->info.si_regs.pc) ||
64 __get_user(npc, &sf->info.si_regs.npc))
65 goto segv;
67 @@ -244,7 +227,7 @@ segv:
68 asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
70 struct rt_signal_frame32 __user *sf;
71 - unsigned int psr, pc, npc, ufp;
72 + unsigned int psr, pc, npc;
73 compat_uptr_t fpu_save;
74 compat_uptr_t rwin_save;
75 sigset_t set;
76 @@ -259,16 +242,11 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
77 sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
79 /* 1. Make sure we are not getting garbage from the user */
80 - if (invalid_frame_pointer(sf, sizeof(*sf)))
81 + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
82 + (((unsigned long) sf) & 3))
83 goto segv;
85 - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
86 - goto segv;
88 - if (ufp & 0x7)
89 - goto segv;
91 - if (__get_user(pc, &sf->regs.pc) ||
92 + if (get_user(pc, &sf->regs.pc) ||
93 __get_user(npc, &sf->regs.npc))
94 goto segv;
96 @@ -329,6 +307,14 @@ segv:
97 force_sig(SIGSEGV, current);
100 +/* Checks if the fp is valid */
101 +static int invalid_frame_pointer(void __user *fp, int fplen)
103 + if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
104 + return 1;
105 + return 0;
108 static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
110 unsigned long sp;
111 diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
112 index c3c12ef..52aa5e4 100644
113 --- a/arch/sparc/kernel/signal_32.c
114 +++ b/arch/sparc/kernel/signal_32.c
115 @@ -60,22 +60,10 @@ struct rt_signal_frame {
116 #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
117 #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
119 -/* Checks if the fp is valid. We always build signal frames which are
120 - * 16-byte aligned, therefore we can always enforce that the restore
121 - * frame has that property as well.
122 - */
123 -static inline bool invalid_frame_pointer(void __user *fp, int fplen)
125 - if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
126 - return true;
128 - return false;
131 asmlinkage void do_sigreturn(struct pt_regs *regs)
133 - unsigned long up_psr, pc, npc, ufp;
134 struct signal_frame __user *sf;
135 + unsigned long up_psr, pc, npc;
136 sigset_t set;
137 __siginfo_fpu_t __user *fpu_save;
138 __siginfo_rwin_t __user *rwin_save;
139 @@ -89,13 +77,10 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
140 sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
142 /* 1. Make sure we are not getting garbage from the user */
143 - if (!invalid_frame_pointer(sf, sizeof(*sf)))
144 - goto segv_and_exit;
146 - if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
147 + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
148 goto segv_and_exit;
150 - if (ufp & 0x7)
151 + if (((unsigned long) sf) & 3)
152 goto segv_and_exit;
154 err = __get_user(pc, &sf->info.si_regs.pc);
155 @@ -142,7 +127,7 @@ segv_and_exit:
156 asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
158 struct rt_signal_frame __user *sf;
159 - unsigned int psr, pc, npc, ufp;
160 + unsigned int psr, pc, npc;
161 __siginfo_fpu_t __user *fpu_save;
162 __siginfo_rwin_t __user *rwin_save;
163 sigset_t set;
164 @@ -150,13 +135,8 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
166 synchronize_user_stack();
167 sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
168 - if (!invalid_frame_pointer(sf, sizeof(*sf)))
169 - goto segv;
171 - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
172 - goto segv;
174 - if (ufp & 0x7)
175 + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
176 + (((unsigned long) sf) & 0x03))
177 goto segv;
179 err = __get_user(pc, &sf->regs.pc);
180 @@ -198,6 +178,15 @@ segv:
181 force_sig(SIGSEGV, current);
184 +/* Checks if the fp is valid */
185 +static inline int invalid_frame_pointer(void __user *fp, int fplen)
187 + if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
188 + return 1;
190 + return 0;
193 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
195 unsigned long sp = regs->u_regs[UREG_FP];
196 diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
197 index 5ee930c..39aaec1 100644
198 --- a/arch/sparc/kernel/signal_64.c
199 +++ b/arch/sparc/kernel/signal_64.c
200 @@ -234,17 +234,6 @@ do_sigsegv:
201 goto out;
204 -/* Checks if the fp is valid. We always build rt signal frames which
205 - * are 16-byte aligned, therefore we can always enforce that the
206 - * restore frame has that property as well.
207 - */
208 -static bool invalid_frame_pointer(void __user *fp)
210 - if (((unsigned long) fp) & 15)
211 - return true;
212 - return false;
215 struct rt_signal_frame {
216 struct sparc_stackf ss;
217 siginfo_t info;
218 @@ -257,8 +246,8 @@ struct rt_signal_frame {
220 void do_rt_sigreturn(struct pt_regs *regs)
222 - unsigned long tpc, tnpc, tstate, ufp;
223 struct rt_signal_frame __user *sf;
224 + unsigned long tpc, tnpc, tstate;
225 __siginfo_fpu_t __user *fpu_save;
226 __siginfo_rwin_t __user *rwin_save;
227 sigset_t set;
228 @@ -272,16 +261,10 @@ void do_rt_sigreturn(struct pt_regs *regs)
229 (regs->u_regs [UREG_FP] + STACK_BIAS);
231 /* 1. Make sure we are not getting garbage from the user */
232 - if (invalid_frame_pointer(sf))
233 - goto segv;
235 - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
236 + if (((unsigned long) sf) & 3)
237 goto segv;
239 - if ((ufp + STACK_BIAS) & 0x7)
240 - goto segv;
242 - err = __get_user(tpc, &sf->regs.tpc);
243 + err = get_user(tpc, &sf->regs.tpc);
244 err |= __get_user(tnpc, &sf->regs.tnpc);
245 if (test_thread_flag(TIF_32BIT)) {
246 tpc &= 0xffffffff;
247 @@ -325,6 +308,14 @@ segv:
248 force_sig(SIGSEGV, current);
251 +/* Checks if the fp is valid */
252 +static int invalid_frame_pointer(void __user *fp)
254 + if (((unsigned long) fp) & 15)
255 + return 1;
256 + return 0;
259 static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
261 unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
262 diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
263 index e5fe8ce..0f6eebe 100644
264 --- a/arch/sparc/kernel/sigutil_32.c
265 +++ b/arch/sparc/kernel/sigutil_32.c
266 @@ -48,10 +48,6 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
267 int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
269 int err;
271 - if (((unsigned long) fpu) & 3)
272 - return -EFAULT;
274 #ifdef CONFIG_SMP
275 if (test_tsk_thread_flag(current, TIF_USEDFPU))
276 regs->psr &= ~PSR_EF;
277 @@ -101,10 +97,7 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
278 struct thread_info *t = current_thread_info();
279 int i, wsaved, err;
281 - if (((unsigned long) rp) & 3)
282 - return -EFAULT;
284 - get_user(wsaved, &rp->wsaved);
285 + __get_user(wsaved, &rp->wsaved);
286 if (wsaved > NSWINS)
287 return -EFAULT;
289 diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
290 index 36aadcb..387834a 100644
291 --- a/arch/sparc/kernel/sigutil_64.c
292 +++ b/arch/sparc/kernel/sigutil_64.c
293 @@ -37,10 +37,7 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
294 unsigned long fprs;
295 int err;
297 - if (((unsigned long) fpu) & 7)
298 - return -EFAULT;
300 - err = get_user(fprs, &fpu->si_fprs);
301 + err = __get_user(fprs, &fpu->si_fprs);
302 fprs_write(0);
303 regs->tstate &= ~TSTATE_PEF;
304 if (fprs & FPRS_DL)
305 @@ -75,10 +72,7 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
306 struct thread_info *t = current_thread_info();
307 int i, wsaved, err;
309 - if (((unsigned long) rp) & 7)
310 - return -EFAULT;
312 - get_user(wsaved, &rp->wsaved);
313 + __get_user(wsaved, &rp->wsaved);
314 if (wsaved > NSWINS)
315 return -EFAULT;
318 1.7.10.4