signal_compat.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/compat.h>
  3. #include <linux/uaccess.h>
  4. #include <linux/ptrace.h>
  5. /*
  6. * The compat_siginfo_t structure and handing code is very easy
  7. * to break in several ways. It must always be updated when new
  8. * updates are made to the main siginfo_t, and
  9. * copy_siginfo_to_user32() must be updated when the
  10. * (arch-independent) copy_siginfo_to_user() is updated.
  11. *
  12. * It is also easy to put a new member in the compat_siginfo_t
  13. * which has implicit alignment which can move internal structure
  14. * alignment around breaking the ABI. This can happen if you,
  15. * for instance, put a plain 64-bit value in there.
  16. */
  17. static inline void signal_compat_build_tests(void)
  18. {
  19. int _sifields_offset = offsetof(compat_siginfo_t, _sifields);
  20. /*
  21. * If adding a new si_code, there is probably new data in
  22. * the siginfo. Make sure folks bumping the si_code
  23. * limits also have to look at this code. Make sure any
  24. * new fields are handled in copy_siginfo_to_user32()!
  25. */
  26. BUILD_BUG_ON(NSIGILL != 11);
  27. BUILD_BUG_ON(NSIGFPE != 15);
  28. BUILD_BUG_ON(NSIGSEGV != 9);
  29. BUILD_BUG_ON(NSIGBUS != 5);
  30. BUILD_BUG_ON(NSIGTRAP != 6);
  31. BUILD_BUG_ON(NSIGCHLD != 6);
  32. BUILD_BUG_ON(NSIGSYS != 2);
  33. /* This is part of the ABI and can never change in size: */
  34. BUILD_BUG_ON(sizeof(siginfo_t) != 128);
  35. BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);
  36. /* This is a part of the ABI and can never change in alignment */
  37. BUILD_BUG_ON(__alignof__(siginfo_t) != 8);
  38. BUILD_BUG_ON(__alignof__(compat_siginfo_t) != 4);
  39. /*
  40. * The offsets of all the (unioned) si_fields are fixed
  41. * in the ABI, of course. Make sure none of them ever
  42. * move and are always at the beginning:
  43. */
  44. BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int));
  45. #define CHECK_CSI_OFFSET(name) BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name))
  46. BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
  47. BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
  48. BUILD_BUG_ON(offsetof(siginfo_t, si_code) != 8);
  49. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0);
  50. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4);
  51. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code) != 8);
  52. /*
  53. * Ensure that the size of each si_field never changes.
  54. * If it does, it is a sign that the
  55. * copy_siginfo_to_user32() code below needs to updated
  56. * along with the size in the CHECK_SI_SIZE().
  57. *
  58. * We repeat this check for both the generic and compat
  59. * siginfos.
  60. *
  61. * Note: it is OK for these to grow as long as the whole
  62. * structure stays within the padding size (checked
  63. * above).
  64. */
  65. #define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name))
  66. #define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name))
  67. CHECK_CSI_OFFSET(_kill);
  68. CHECK_CSI_SIZE (_kill, 2*sizeof(int));
  69. CHECK_SI_SIZE (_kill, 2*sizeof(int));
  70. BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
  71. BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
  72. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC);
  73. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
  74. CHECK_CSI_OFFSET(_timer);
  75. CHECK_CSI_SIZE (_timer, 3*sizeof(int));
  76. CHECK_SI_SIZE (_timer, 6*sizeof(int));
  77. BUILD_BUG_ON(offsetof(siginfo_t, si_tid) != 0x10);
  78. BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14);
  79. BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
  80. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid) != 0x0C);
  81. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10);
  82. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);
  83. CHECK_CSI_OFFSET(_rt);
  84. CHECK_CSI_SIZE (_rt, 3*sizeof(int));
  85. CHECK_SI_SIZE (_rt, 4*sizeof(int));
  86. BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
  87. BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
  88. BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
  89. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0x0C);
  90. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
  91. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);
  92. CHECK_CSI_OFFSET(_sigchld);
  93. CHECK_CSI_SIZE (_sigchld, 5*sizeof(int));
  94. CHECK_SI_SIZE (_sigchld, 8*sizeof(int));
  95. BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
  96. BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
  97. BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18);
  98. BUILD_BUG_ON(offsetof(siginfo_t, si_utime) != 0x20);
  99. BUILD_BUG_ON(offsetof(siginfo_t, si_stime) != 0x28);
  100. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0x0C);
  101. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
  102. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14);
  103. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime) != 0x18);
  104. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime) != 0x1C);
  105. #ifdef CONFIG_X86_X32_ABI
  106. CHECK_CSI_OFFSET(_sigchld_x32);
  107. CHECK_CSI_SIZE (_sigchld_x32, 7*sizeof(int));
  108. /* no _sigchld_x32 in the generic siginfo_t */
  109. BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) != 0x18);
  110. BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) != 0x20);
  111. #endif
  112. CHECK_CSI_OFFSET(_sigfault);
  113. CHECK_CSI_SIZE (_sigfault, 4*sizeof(int));
  114. CHECK_SI_SIZE (_sigfault, 8*sizeof(int));
  115. BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
  116. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
  117. BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18);
  118. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10);
  119. BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
  120. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
  121. BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
  122. BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
  123. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
  124. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);
  125. BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
  126. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
  127. BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18);
  128. BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20);
  129. BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x24);
  130. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10);
  131. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14);
  132. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_flags) != 0x18);
  133. CHECK_CSI_OFFSET(_sigpoll);
  134. CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
  135. CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
  136. BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x10);
  137. BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x18);
  138. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
  139. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd) != 0x10);
  140. CHECK_CSI_OFFSET(_sigsys);
  141. CHECK_CSI_SIZE (_sigsys, 3*sizeof(int));
  142. CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
  143. BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
  144. BUILD_BUG_ON(offsetof(siginfo_t, si_syscall) != 0x18);
  145. BUILD_BUG_ON(offsetof(siginfo_t, si_arch) != 0x1C);
  146. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
  147. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall) != 0x10);
  148. BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch) != 0x14);
  149. /* any new si_fields should be added here */
  150. }
  151. void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
  152. {
  153. signal_compat_build_tests();
  154. if (!act)
  155. return;
  156. if (in_ia32_syscall())
  157. act->sa.sa_flags |= SA_IA32_ABI;
  158. if (in_x32_syscall())
  159. act->sa.sa_flags |= SA_X32_ABI;
  160. }