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
6 we wrongly defined a dummy SA_RESTORER flag on these archs, despite
7 the kernel interface not actually having such a feature. on archs
8 which lack SA_RESTORER, the kernel sigaction structure also lacks the
9 restorer function pointer member, which means the signal mask appears
10 at a different offset. the kernel was thereby interpreting the bits of
11 the code address as part of the signal set to be masked while handling
14 this patch removes the erroneous SA_RESTORER definitions from archs
15 which do not have it, makes access to the member conditional on
16 whether SA_RESTORER is defined for the arch, and removes the
17 now-unused asm for the affected archs.
19 because there are reportedly versions of qemu-user which also use the
20 wrong ABI here, the old ksigaction struct size is preserved with an
21 unused member at the end. this is harmless and mitigates the risk of
22 such a bug turning into a buffer overflow onto the sigaction
25 arch/microblaze/bits/signal.h | 1 -
26 arch/mips/bits/signal.h | 1 -
27 arch/mips/ksigaction.h | 5 +----
28 arch/mips64/bits/signal.h | 1 -
29 arch/mips64/ksigaction.h | 2 +-
30 arch/mipsn32/bits/signal.h | 1 -
31 arch/mipsn32/ksigaction.h | 2 +-
32 arch/or1k/bits/signal.h | 1 -
33 arch/riscv64/bits/signal.h | 1 -
34 src/internal/ksigaction.h | 5 +++++
35 src/signal/mips/restore.s | 15 ---------------
36 src/signal/mips64/restore.s | 11 -----------
37 src/signal/mipsn32/restore.s | 11 -----------
38 src/signal/sigaction.c | 5 ++++-
39 14 files changed, 12 insertions(+), 50 deletions(-)
40 delete mode 100644 src/signal/mips/restore.s
41 delete mode 100644 src/signal/mips64/restore.s
42 delete mode 100644 src/signal/mipsn32/restore.s
44 diff --git a/arch/microblaze/bits/signal.h b/arch/microblaze/bits/signal.h
45 index 490f83bf..f25b7c6a 100644
46 --- a/arch/microblaze/bits/signal.h
47 +++ b/arch/microblaze/bits/signal.h
48 @@ -46,7 +46,6 @@ typedef struct __ucontext {
49 #define SA_RESTART 0x10000000
50 #define SA_NODEFER 0x40000000
51 #define SA_RESETHAND 0x80000000
52 -#define SA_RESTORER 0x04000000
56 diff --git a/arch/mips/bits/signal.h b/arch/mips/bits/signal.h
57 index 1b69e762..a3b3857a 100644
58 --- a/arch/mips/bits/signal.h
59 +++ b/arch/mips/bits/signal.h
60 @@ -66,7 +66,6 @@ typedef struct __ucontext {
61 #define SA_RESTART 0x10000000
62 #define SA_NODEFER 0x40000000
63 #define SA_RESETHAND 0x80000000
64 -#define SA_RESTORER 0x04000000
68 diff --git a/arch/mips/ksigaction.h b/arch/mips/ksigaction.h
69 index 63fdfab0..485abf75 100644
70 --- a/arch/mips/ksigaction.h
71 +++ b/arch/mips/ksigaction.h
72 @@ -4,10 +4,7 @@ struct k_sigaction {
75 unsigned long mask[4];
76 - /* The following field is past the end of the structure the
77 - * kernel will read or write, and exists only to avoid having
78 - * mips-specific preprocessor conditionals in sigaction.c. */
83 hidden void __restore(), __restore_rt();
84 diff --git a/arch/mips64/bits/signal.h b/arch/mips64/bits/signal.h
85 index 4f91c9fc..ffec7fd0 100644
86 --- a/arch/mips64/bits/signal.h
87 +++ b/arch/mips64/bits/signal.h
88 @@ -85,7 +85,6 @@ typedef struct __ucontext {
89 #define SA_RESTART 0x10000000
90 #define SA_NODEFER 0x40000000
91 #define SA_RESETHAND 0x80000000
92 -#define SA_RESTORER 0x04000000
96 diff --git a/arch/mips64/ksigaction.h b/arch/mips64/ksigaction.h
97 index c16e4731..b4d0fa5f 100644
98 --- a/arch/mips64/ksigaction.h
99 +++ b/arch/mips64/ksigaction.h
100 @@ -4,7 +4,7 @@ struct k_sigaction {
102 void (*handler)(int);
103 unsigned long mask[2];
104 - void (*restorer)();
108 hidden void __restore(), __restore_rt();
109 diff --git a/arch/mipsn32/bits/signal.h b/arch/mipsn32/bits/signal.h
110 index 4f91c9fc..ffec7fd0 100644
111 --- a/arch/mipsn32/bits/signal.h
112 +++ b/arch/mipsn32/bits/signal.h
113 @@ -85,7 +85,6 @@ typedef struct __ucontext {
114 #define SA_RESTART 0x10000000
115 #define SA_NODEFER 0x40000000
116 #define SA_RESETHAND 0x80000000
117 -#define SA_RESTORER 0x04000000
121 diff --git a/arch/mipsn32/ksigaction.h b/arch/mipsn32/ksigaction.h
122 index b565f1fc..485abf75 100644
123 --- a/arch/mipsn32/ksigaction.h
124 +++ b/arch/mipsn32/ksigaction.h
125 @@ -4,7 +4,7 @@ struct k_sigaction {
127 void (*handler)(int);
128 unsigned long mask[4];
129 - void (*restorer)();
133 hidden void __restore(), __restore_rt();
134 diff --git a/arch/or1k/bits/signal.h b/arch/or1k/bits/signal.h
135 index be576d1d..c45be676 100644
136 --- a/arch/or1k/bits/signal.h
137 +++ b/arch/or1k/bits/signal.h
138 @@ -43,7 +43,6 @@ typedef struct __ucontext {
139 #define SA_RESTART 0x10000000
140 #define SA_NODEFER 0x40000000
141 #define SA_RESETHAND 0x80000000
142 -#define SA_RESTORER 0x04000000
146 diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h
147 index 287367db..fd6157a3 100644
148 --- a/arch/riscv64/bits/signal.h
149 +++ b/arch/riscv64/bits/signal.h
150 @@ -76,7 +76,6 @@ typedef struct __ucontext
151 #define SA_RESTART 0x10000000
152 #define SA_NODEFER 0x40000000
153 #define SA_RESETHAND 0x80000000
154 -#define SA_RESTORER 0x04000000
158 diff --git a/src/internal/ksigaction.h b/src/internal/ksigaction.h
159 index 8ebd5938..ef333f33 100644
160 --- a/src/internal/ksigaction.h
161 +++ b/src/internal/ksigaction.h
164 void (*handler)(int);
167 void (*restorer)(void);
175 hidden void __restore(), __restore_rt();
176 diff --git a/src/signal/mips/restore.s b/src/signal/mips/restore.s
177 deleted file mode 100644
178 index b6dadce0..00000000
179 --- a/src/signal/mips/restore.s
184 -.global __restore_rt
185 -.hidden __restore_rt
186 -.type __restore_rt,@function
193 -.type __restore,@function
197 diff --git a/src/signal/mips64/restore.s b/src/signal/mips64/restore.s
198 deleted file mode 100644
199 index 401f8e73..00000000
200 --- a/src/signal/mips64/restore.s
204 -.global __restore_rt
206 -.hidden __restore_rt
208 -.type __restore_rt,@function
209 -.type __restore,@function
214 diff --git a/src/signal/mipsn32/restore.s b/src/signal/mipsn32/restore.s
215 deleted file mode 100644
216 index 4cd4e1b4..00000000
217 --- a/src/signal/mipsn32/restore.s
221 -.global __restore_rt
223 -.hidden __restore_rt
225 -.type __restore_rt,@function
226 -.type __restore,@function
231 diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
232 index 2203471b..e45308fa 100644
233 --- a/src/signal/sigaction.c
234 +++ b/src/signal/sigaction.c
235 @@ -44,8 +44,11 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
238 ksa.handler = sa->sa_handler;
239 - ksa.flags = sa->sa_flags | SA_RESTORER;
240 + ksa.flags = sa->sa_flags;
242 + ksa.flags |= SA_RESTORER;
243 ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
245 memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
247 int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);