269d193820342dc109f39909d78fb30f4c978f76 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. From 269d193820342dc109f39909d78fb30f4c978f76 Mon Sep 17 00:00:00 2001
  2. From: Rich Felker <dalias@aerifal.cx>
  3. Date: Thu, 9 Feb 2023 11:52:44 -0500
  4. Subject: fix wrong sigaction syscall ABI on mips*, or1k, microblaze, riscv64
  5. we wrongly defined a dummy SA_RESTORER flag on these archs, despite
  6. the kernel interface not actually having such a feature. on archs
  7. which lack SA_RESTORER, the kernel sigaction structure also lacks the
  8. restorer function pointer member, which means the signal mask appears
  9. at a different offset. the kernel was thereby interpreting the bits of
  10. the code address as part of the signal set to be masked while handling
  11. the signal.
  12. this patch removes the erroneous SA_RESTORER definitions from archs
  13. which do not have it, makes access to the member conditional on
  14. whether SA_RESTORER is defined for the arch, and removes the
  15. now-unused asm for the affected archs.
  16. because there are reportedly versions of qemu-user which also use the
  17. wrong ABI here, the old ksigaction struct size is preserved with an
  18. unused member at the end. this is harmless and mitigates the risk of
  19. such a bug turning into a buffer overflow onto the sigaction
  20. function's stack.
  21. ---
  22. arch/microblaze/bits/signal.h | 1 -
  23. arch/mips/bits/signal.h | 1 -
  24. arch/mips/ksigaction.h | 5 +----
  25. arch/mips64/bits/signal.h | 1 -
  26. arch/mips64/ksigaction.h | 2 +-
  27. arch/mipsn32/bits/signal.h | 1 -
  28. arch/mipsn32/ksigaction.h | 2 +-
  29. arch/or1k/bits/signal.h | 1 -
  30. arch/riscv64/bits/signal.h | 1 -
  31. src/internal/ksigaction.h | 5 +++++
  32. src/signal/mips/restore.s | 15 ---------------
  33. src/signal/mips64/restore.s | 11 -----------
  34. src/signal/mipsn32/restore.s | 11 -----------
  35. src/signal/sigaction.c | 5 ++++-
  36. 14 files changed, 12 insertions(+), 50 deletions(-)
  37. delete mode 100644 src/signal/mips/restore.s
  38. delete mode 100644 src/signal/mips64/restore.s
  39. delete mode 100644 src/signal/mipsn32/restore.s
  40. diff --git a/arch/microblaze/bits/signal.h b/arch/microblaze/bits/signal.h
  41. index 490f83bf..f25b7c6a 100644
  42. --- a/arch/microblaze/bits/signal.h
  43. +++ b/arch/microblaze/bits/signal.h
  44. @@ -46,7 +46,6 @@ typedef struct __ucontext {
  45. #define SA_RESTART 0x10000000
  46. #define SA_NODEFER 0x40000000
  47. #define SA_RESETHAND 0x80000000
  48. -#define SA_RESTORER 0x04000000
  49. #endif
  50. diff --git a/arch/mips/bits/signal.h b/arch/mips/bits/signal.h
  51. index 1b69e762..a3b3857a 100644
  52. --- a/arch/mips/bits/signal.h
  53. +++ b/arch/mips/bits/signal.h
  54. @@ -66,7 +66,6 @@ typedef struct __ucontext {
  55. #define SA_RESTART 0x10000000
  56. #define SA_NODEFER 0x40000000
  57. #define SA_RESETHAND 0x80000000
  58. -#define SA_RESTORER 0x04000000
  59. #undef SIG_BLOCK
  60. #undef SIG_UNBLOCK
  61. diff --git a/arch/mips/ksigaction.h b/arch/mips/ksigaction.h
  62. index 63fdfab0..485abf75 100644
  63. --- a/arch/mips/ksigaction.h
  64. +++ b/arch/mips/ksigaction.h
  65. @@ -4,10 +4,7 @@ struct k_sigaction {
  66. unsigned flags;
  67. void (*handler)(int);
  68. unsigned long mask[4];
  69. - /* The following field is past the end of the structure the
  70. - * kernel will read or write, and exists only to avoid having
  71. - * mips-specific preprocessor conditionals in sigaction.c. */
  72. - void (*restorer)();
  73. + void *unused;
  74. };
  75. hidden void __restore(), __restore_rt();
  76. diff --git a/arch/mips64/bits/signal.h b/arch/mips64/bits/signal.h
  77. index 4f91c9fc..ffec7fd0 100644
  78. --- a/arch/mips64/bits/signal.h
  79. +++ b/arch/mips64/bits/signal.h
  80. @@ -85,7 +85,6 @@ typedef struct __ucontext {
  81. #define SA_RESTART 0x10000000
  82. #define SA_NODEFER 0x40000000
  83. #define SA_RESETHAND 0x80000000
  84. -#define SA_RESTORER 0x04000000
  85. #undef SIG_BLOCK
  86. #undef SIG_UNBLOCK
  87. diff --git a/arch/mips64/ksigaction.h b/arch/mips64/ksigaction.h
  88. index c16e4731..b4d0fa5f 100644
  89. --- a/arch/mips64/ksigaction.h
  90. +++ b/arch/mips64/ksigaction.h
  91. @@ -4,7 +4,7 @@ struct k_sigaction {
  92. unsigned flags;
  93. void (*handler)(int);
  94. unsigned long mask[2];
  95. - void (*restorer)();
  96. + void *unused;
  97. };
  98. hidden void __restore(), __restore_rt();
  99. diff --git a/arch/mipsn32/bits/signal.h b/arch/mipsn32/bits/signal.h
  100. index 4f91c9fc..ffec7fd0 100644
  101. --- a/arch/mipsn32/bits/signal.h
  102. +++ b/arch/mipsn32/bits/signal.h
  103. @@ -85,7 +85,6 @@ typedef struct __ucontext {
  104. #define SA_RESTART 0x10000000
  105. #define SA_NODEFER 0x40000000
  106. #define SA_RESETHAND 0x80000000
  107. -#define SA_RESTORER 0x04000000
  108. #undef SIG_BLOCK
  109. #undef SIG_UNBLOCK
  110. diff --git a/arch/mipsn32/ksigaction.h b/arch/mipsn32/ksigaction.h
  111. index b565f1fc..485abf75 100644
  112. --- a/arch/mipsn32/ksigaction.h
  113. +++ b/arch/mipsn32/ksigaction.h
  114. @@ -4,7 +4,7 @@ struct k_sigaction {
  115. unsigned flags;
  116. void (*handler)(int);
  117. unsigned long mask[4];
  118. - void (*restorer)();
  119. + void *unused;
  120. };
  121. hidden void __restore(), __restore_rt();
  122. diff --git a/arch/or1k/bits/signal.h b/arch/or1k/bits/signal.h
  123. index be576d1d..c45be676 100644
  124. --- a/arch/or1k/bits/signal.h
  125. +++ b/arch/or1k/bits/signal.h
  126. @@ -43,7 +43,6 @@ typedef struct __ucontext {
  127. #define SA_RESTART 0x10000000
  128. #define SA_NODEFER 0x40000000
  129. #define SA_RESETHAND 0x80000000
  130. -#define SA_RESTORER 0x04000000
  131. #endif
  132. diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h
  133. index 287367db..fd6157a3 100644
  134. --- a/arch/riscv64/bits/signal.h
  135. +++ b/arch/riscv64/bits/signal.h
  136. @@ -76,7 +76,6 @@ typedef struct __ucontext
  137. #define SA_RESTART 0x10000000
  138. #define SA_NODEFER 0x40000000
  139. #define SA_RESETHAND 0x80000000
  140. -#define SA_RESTORER 0x04000000
  141. #endif
  142. diff --git a/src/internal/ksigaction.h b/src/internal/ksigaction.h
  143. index 8ebd5938..ef333f33 100644
  144. --- a/src/internal/ksigaction.h
  145. +++ b/src/internal/ksigaction.h
  146. @@ -6,8 +6,13 @@
  147. struct k_sigaction {
  148. void (*handler)(int);
  149. unsigned long flags;
  150. +#ifdef SA_RESTORER
  151. void (*restorer)(void);
  152. +#endif
  153. unsigned mask[2];
  154. +#ifndef SA_RESTORER
  155. + void *unused;
  156. +#endif
  157. };
  158. hidden void __restore(), __restore_rt();
  159. diff --git a/src/signal/mips/restore.s b/src/signal/mips/restore.s
  160. deleted file mode 100644
  161. index b6dadce0..00000000
  162. --- a/src/signal/mips/restore.s
  163. +++ /dev/null
  164. @@ -1,15 +0,0 @@
  165. -.set noreorder
  166. -
  167. -.global __restore_rt
  168. -.hidden __restore_rt
  169. -.type __restore_rt,@function
  170. -__restore_rt:
  171. - li $2, 4193
  172. - syscall
  173. -
  174. -.global __restore
  175. -.hidden __restore
  176. -.type __restore,@function
  177. -__restore:
  178. - li $2, 4119
  179. - syscall
  180. diff --git a/src/signal/mips64/restore.s b/src/signal/mips64/restore.s
  181. deleted file mode 100644
  182. index 401f8e73..00000000
  183. --- a/src/signal/mips64/restore.s
  184. +++ /dev/null
  185. @@ -1,11 +0,0 @@
  186. -.set noreorder
  187. -.global __restore_rt
  188. -.global __restore
  189. -.hidden __restore_rt
  190. -.hidden __restore
  191. -.type __restore_rt,@function
  192. -.type __restore,@function
  193. -__restore_rt:
  194. -__restore:
  195. - li $2,5211
  196. - syscall
  197. diff --git a/src/signal/mipsn32/restore.s b/src/signal/mipsn32/restore.s
  198. deleted file mode 100644
  199. index 4cd4e1b4..00000000
  200. --- a/src/signal/mipsn32/restore.s
  201. +++ /dev/null
  202. @@ -1,11 +0,0 @@
  203. -.set noreorder
  204. -.global __restore_rt
  205. -.global __restore
  206. -.hidden __restore_rt
  207. -.hidden __restore
  208. -.type __restore_rt,@function
  209. -.type __restore,@function
  210. -__restore_rt:
  211. -__restore:
  212. - li $2,6211
  213. - syscall
  214. diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
  215. index 2203471b..e45308fa 100644
  216. --- a/src/signal/sigaction.c
  217. +++ b/src/signal/sigaction.c
  218. @@ -44,8 +44,11 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
  219. }
  220. }
  221. ksa.handler = sa->sa_handler;
  222. - ksa.flags = sa->sa_flags | SA_RESTORER;
  223. + ksa.flags = sa->sa_flags;
  224. +#ifdef SA_RESTORER
  225. + ksa.flags |= SA_RESTORER;
  226. ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
  227. +#endif
  228. memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
  229. }
  230. int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
  231. --
  232. cgit v1.2.1