revert-sparc.patch 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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."
  5. This reverts commit 1fda90c39d8ef6acbedfd3cd9bd710a5bcc490c3.
  6. Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
  7. ---
  8. arch/sparc/kernel/signal32.c | 46 ++++++++++++++--------------------------
  9. arch/sparc/kernel/signal_32.c | 41 +++++++++++++----------------------
  10. arch/sparc/kernel/signal_64.c | 31 ++++++++++-----------------
  11. arch/sparc/kernel/sigutil_32.c | 9 +-------
  12. arch/sparc/kernel/sigutil_64.c | 10 ++-------
  13. 5 files changed, 45 insertions(+), 92 deletions(-)
  14. diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
  15. index 77655f0..4eed773 100644
  16. --- a/arch/sparc/kernel/signal32.c
  17. +++ b/arch/sparc/kernel/signal32.c
  18. @@ -138,24 +138,12 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
  19. return 0;
  20. }
  21. -/* Checks if the fp is valid. We always build signal frames which are
  22. - * 16-byte aligned, therefore we can always enforce that the restore
  23. - * frame has that property as well.
  24. - */
  25. -static bool invalid_frame_pointer(void __user *fp, int fplen)
  26. -{
  27. - if ((((unsigned long) fp) & 15) ||
  28. - ((unsigned long)fp) > 0x100000000ULL - fplen)
  29. - return true;
  30. - return false;
  31. -}
  32. -
  33. void do_sigreturn32(struct pt_regs *regs)
  34. {
  35. struct signal_frame32 __user *sf;
  36. compat_uptr_t fpu_save;
  37. compat_uptr_t rwin_save;
  38. - unsigned int psr, ufp;
  39. + unsigned int psr;
  40. unsigned pc, npc;
  41. sigset_t set;
  42. compat_sigset_t seta;
  43. @@ -170,16 +158,11 @@ void do_sigreturn32(struct pt_regs *regs)
  44. sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
  45. /* 1. Make sure we are not getting garbage from the user */
  46. - if (invalid_frame_pointer(sf, sizeof(*sf)))
  47. - goto segv;
  48. -
  49. - if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
  50. - goto segv;
  51. -
  52. - if (ufp & 0x7)
  53. + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
  54. + (((unsigned long) sf) & 3))
  55. goto segv;
  56. - if (__get_user(pc, &sf->info.si_regs.pc) ||
  57. + if (get_user(pc, &sf->info.si_regs.pc) ||
  58. __get_user(npc, &sf->info.si_regs.npc))
  59. goto segv;
  60. @@ -244,7 +227,7 @@ segv:
  61. asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
  62. {
  63. struct rt_signal_frame32 __user *sf;
  64. - unsigned int psr, pc, npc, ufp;
  65. + unsigned int psr, pc, npc;
  66. compat_uptr_t fpu_save;
  67. compat_uptr_t rwin_save;
  68. sigset_t set;
  69. @@ -259,16 +242,11 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
  70. sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
  71. /* 1. Make sure we are not getting garbage from the user */
  72. - if (invalid_frame_pointer(sf, sizeof(*sf)))
  73. + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
  74. + (((unsigned long) sf) & 3))
  75. goto segv;
  76. - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
  77. - goto segv;
  78. -
  79. - if (ufp & 0x7)
  80. - goto segv;
  81. -
  82. - if (__get_user(pc, &sf->regs.pc) ||
  83. + if (get_user(pc, &sf->regs.pc) ||
  84. __get_user(npc, &sf->regs.npc))
  85. goto segv;
  86. @@ -329,6 +307,14 @@ segv:
  87. force_sig(SIGSEGV, current);
  88. }
  89. +/* Checks if the fp is valid */
  90. +static int invalid_frame_pointer(void __user *fp, int fplen)
  91. +{
  92. + if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
  93. + return 1;
  94. + return 0;
  95. +}
  96. +
  97. static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
  98. {
  99. unsigned long sp;
  100. diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
  101. index c3c12ef..52aa5e4 100644
  102. --- a/arch/sparc/kernel/signal_32.c
  103. +++ b/arch/sparc/kernel/signal_32.c
  104. @@ -60,22 +60,10 @@ struct rt_signal_frame {
  105. #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
  106. #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
  107. -/* Checks if the fp is valid. We always build signal frames which are
  108. - * 16-byte aligned, therefore we can always enforce that the restore
  109. - * frame has that property as well.
  110. - */
  111. -static inline bool invalid_frame_pointer(void __user *fp, int fplen)
  112. -{
  113. - if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
  114. - return true;
  115. -
  116. - return false;
  117. -}
  118. -
  119. asmlinkage void do_sigreturn(struct pt_regs *regs)
  120. {
  121. - unsigned long up_psr, pc, npc, ufp;
  122. struct signal_frame __user *sf;
  123. + unsigned long up_psr, pc, npc;
  124. sigset_t set;
  125. __siginfo_fpu_t __user *fpu_save;
  126. __siginfo_rwin_t __user *rwin_save;
  127. @@ -89,13 +77,10 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
  128. sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
  129. /* 1. Make sure we are not getting garbage from the user */
  130. - if (!invalid_frame_pointer(sf, sizeof(*sf)))
  131. - goto segv_and_exit;
  132. -
  133. - if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
  134. + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
  135. goto segv_and_exit;
  136. - if (ufp & 0x7)
  137. + if (((unsigned long) sf) & 3)
  138. goto segv_and_exit;
  139. err = __get_user(pc, &sf->info.si_regs.pc);
  140. @@ -142,7 +127,7 @@ segv_and_exit:
  141. asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
  142. {
  143. struct rt_signal_frame __user *sf;
  144. - unsigned int psr, pc, npc, ufp;
  145. + unsigned int psr, pc, npc;
  146. __siginfo_fpu_t __user *fpu_save;
  147. __siginfo_rwin_t __user *rwin_save;
  148. sigset_t set;
  149. @@ -150,13 +135,8 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
  150. synchronize_user_stack();
  151. sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
  152. - if (!invalid_frame_pointer(sf, sizeof(*sf)))
  153. - goto segv;
  154. -
  155. - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
  156. - goto segv;
  157. -
  158. - if (ufp & 0x7)
  159. + if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
  160. + (((unsigned long) sf) & 0x03))
  161. goto segv;
  162. err = __get_user(pc, &sf->regs.pc);
  163. @@ -198,6 +178,15 @@ segv:
  164. force_sig(SIGSEGV, current);
  165. }
  166. +/* Checks if the fp is valid */
  167. +static inline int invalid_frame_pointer(void __user *fp, int fplen)
  168. +{
  169. + if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
  170. + return 1;
  171. +
  172. + return 0;
  173. +}
  174. +
  175. static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
  176. {
  177. unsigned long sp = regs->u_regs[UREG_FP];
  178. diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
  179. index 5ee930c..39aaec1 100644
  180. --- a/arch/sparc/kernel/signal_64.c
  181. +++ b/arch/sparc/kernel/signal_64.c
  182. @@ -234,17 +234,6 @@ do_sigsegv:
  183. goto out;
  184. }
  185. -/* Checks if the fp is valid. We always build rt signal frames which
  186. - * are 16-byte aligned, therefore we can always enforce that the
  187. - * restore frame has that property as well.
  188. - */
  189. -static bool invalid_frame_pointer(void __user *fp)
  190. -{
  191. - if (((unsigned long) fp) & 15)
  192. - return true;
  193. - return false;
  194. -}
  195. -
  196. struct rt_signal_frame {
  197. struct sparc_stackf ss;
  198. siginfo_t info;
  199. @@ -257,8 +246,8 @@ struct rt_signal_frame {
  200. void do_rt_sigreturn(struct pt_regs *regs)
  201. {
  202. - unsigned long tpc, tnpc, tstate, ufp;
  203. struct rt_signal_frame __user *sf;
  204. + unsigned long tpc, tnpc, tstate;
  205. __siginfo_fpu_t __user *fpu_save;
  206. __siginfo_rwin_t __user *rwin_save;
  207. sigset_t set;
  208. @@ -272,16 +261,10 @@ void do_rt_sigreturn(struct pt_regs *regs)
  209. (regs->u_regs [UREG_FP] + STACK_BIAS);
  210. /* 1. Make sure we are not getting garbage from the user */
  211. - if (invalid_frame_pointer(sf))
  212. - goto segv;
  213. -
  214. - if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
  215. + if (((unsigned long) sf) & 3)
  216. goto segv;
  217. - if ((ufp + STACK_BIAS) & 0x7)
  218. - goto segv;
  219. -
  220. - err = __get_user(tpc, &sf->regs.tpc);
  221. + err = get_user(tpc, &sf->regs.tpc);
  222. err |= __get_user(tnpc, &sf->regs.tnpc);
  223. if (test_thread_flag(TIF_32BIT)) {
  224. tpc &= 0xffffffff;
  225. @@ -325,6 +308,14 @@ segv:
  226. force_sig(SIGSEGV, current);
  227. }
  228. +/* Checks if the fp is valid */
  229. +static int invalid_frame_pointer(void __user *fp)
  230. +{
  231. + if (((unsigned long) fp) & 15)
  232. + return 1;
  233. + return 0;
  234. +}
  235. +
  236. static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
  237. {
  238. unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
  239. diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
  240. index e5fe8ce..0f6eebe 100644
  241. --- a/arch/sparc/kernel/sigutil_32.c
  242. +++ b/arch/sparc/kernel/sigutil_32.c
  243. @@ -48,10 +48,6 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
  244. int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
  245. {
  246. int err;
  247. -
  248. - if (((unsigned long) fpu) & 3)
  249. - return -EFAULT;
  250. -
  251. #ifdef CONFIG_SMP
  252. if (test_tsk_thread_flag(current, TIF_USEDFPU))
  253. regs->psr &= ~PSR_EF;
  254. @@ -101,10 +97,7 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
  255. struct thread_info *t = current_thread_info();
  256. int i, wsaved, err;
  257. - if (((unsigned long) rp) & 3)
  258. - return -EFAULT;
  259. -
  260. - get_user(wsaved, &rp->wsaved);
  261. + __get_user(wsaved, &rp->wsaved);
  262. if (wsaved > NSWINS)
  263. return -EFAULT;
  264. diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
  265. index 36aadcb..387834a 100644
  266. --- a/arch/sparc/kernel/sigutil_64.c
  267. +++ b/arch/sparc/kernel/sigutil_64.c
  268. @@ -37,10 +37,7 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
  269. unsigned long fprs;
  270. int err;
  271. - if (((unsigned long) fpu) & 7)
  272. - return -EFAULT;
  273. -
  274. - err = get_user(fprs, &fpu->si_fprs);
  275. + err = __get_user(fprs, &fpu->si_fprs);
  276. fprs_write(0);
  277. regs->tstate &= ~TSTATE_PEF;
  278. if (fprs & FPRS_DL)
  279. @@ -75,10 +72,7 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
  280. struct thread_info *t = current_thread_info();
  281. int i, wsaved, err;
  282. - if (((unsigned long) rp) & 7)
  283. - return -EFAULT;
  284. -
  285. - get_user(wsaved, &rp->wsaved);
  286. + __get_user(wsaved, &rp->wsaved);
  287. if (wsaved > NSWINS)
  288. return -EFAULT;
  289. --
  290. 1.7.10.4