| .. | .. |
|---|
| 11 | 11 | /* for sysctl */ |
|---|
| 12 | 12 | extern int print_fatal_signals; |
|---|
| 13 | 13 | |
|---|
| 14 | | -static inline void copy_siginfo(struct siginfo *to, const struct siginfo *from) |
|---|
| 14 | +static inline void copy_siginfo(kernel_siginfo_t *to, |
|---|
| 15 | + const kernel_siginfo_t *from) |
|---|
| 15 | 16 | { |
|---|
| 16 | 17 | memcpy(to, from, sizeof(*to)); |
|---|
| 17 | 18 | } |
|---|
| 18 | 19 | |
|---|
| 19 | | -static inline void clear_siginfo(struct siginfo *info) |
|---|
| 20 | +static inline void clear_siginfo(kernel_siginfo_t *info) |
|---|
| 20 | 21 | { |
|---|
| 21 | 22 | memset(info, 0, sizeof(*info)); |
|---|
| 22 | 23 | } |
|---|
| 23 | 24 | |
|---|
| 24 | | -int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); |
|---|
| 25 | +#define SI_EXPANSION_SIZE (sizeof(struct siginfo) - sizeof(struct kernel_siginfo)) |
|---|
| 26 | + |
|---|
| 27 | +static inline void copy_siginfo_to_external(siginfo_t *to, |
|---|
| 28 | + const kernel_siginfo_t *from) |
|---|
| 29 | +{ |
|---|
| 30 | + memcpy(to, from, sizeof(*from)); |
|---|
| 31 | + memset(((char *)to) + sizeof(struct kernel_siginfo), 0, |
|---|
| 32 | + SI_EXPANSION_SIZE); |
|---|
| 33 | +} |
|---|
| 34 | + |
|---|
| 35 | +int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from); |
|---|
| 36 | +int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from); |
|---|
| 25 | 37 | |
|---|
| 26 | 38 | enum siginfo_layout { |
|---|
| 27 | 39 | SIL_KILL, |
|---|
| .. | .. |
|---|
| 125 | 137 | b3 = b->sig[3]; b2 = b->sig[2]; \ |
|---|
| 126 | 138 | r->sig[3] = op(a3, b3); \ |
|---|
| 127 | 139 | r->sig[2] = op(a2, b2); \ |
|---|
| 140 | + fallthrough; \ |
|---|
| 128 | 141 | case 2: \ |
|---|
| 129 | 142 | a1 = a->sig[1]; b1 = b->sig[1]; \ |
|---|
| 130 | 143 | r->sig[1] = op(a1, b1); \ |
|---|
| 144 | + fallthrough; \ |
|---|
| 131 | 145 | case 1: \ |
|---|
| 132 | 146 | a0 = a->sig[0]; b0 = b->sig[0]; \ |
|---|
| 133 | 147 | r->sig[0] = op(a0, b0); \ |
|---|
| .. | .. |
|---|
| 157 | 171 | switch (_NSIG_WORDS) { \ |
|---|
| 158 | 172 | case 4: set->sig[3] = op(set->sig[3]); \ |
|---|
| 159 | 173 | set->sig[2] = op(set->sig[2]); \ |
|---|
| 174 | + fallthrough; \ |
|---|
| 160 | 175 | case 2: set->sig[1] = op(set->sig[1]); \ |
|---|
| 176 | + fallthrough; \ |
|---|
| 161 | 177 | case 1: set->sig[0] = op(set->sig[0]); \ |
|---|
| 162 | 178 | break; \ |
|---|
| 163 | 179 | default: \ |
|---|
| .. | .. |
|---|
| 178 | 194 | memset(set, 0, sizeof(sigset_t)); |
|---|
| 179 | 195 | break; |
|---|
| 180 | 196 | case 2: set->sig[1] = 0; |
|---|
| 197 | + fallthrough; |
|---|
| 181 | 198 | case 1: set->sig[0] = 0; |
|---|
| 182 | 199 | break; |
|---|
| 183 | 200 | } |
|---|
| .. | .. |
|---|
| 190 | 207 | memset(set, -1, sizeof(sigset_t)); |
|---|
| 191 | 208 | break; |
|---|
| 192 | 209 | case 2: set->sig[1] = -1; |
|---|
| 210 | + fallthrough; |
|---|
| 193 | 211 | case 1: set->sig[0] = -1; |
|---|
| 194 | 212 | break; |
|---|
| 195 | 213 | } |
|---|
| .. | .. |
|---|
| 220 | 238 | memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1)); |
|---|
| 221 | 239 | break; |
|---|
| 222 | 240 | case 2: set->sig[1] = 0; |
|---|
| 241 | + break; |
|---|
| 223 | 242 | case 1: ; |
|---|
| 224 | 243 | } |
|---|
| 225 | 244 | } |
|---|
| .. | .. |
|---|
| 232 | 251 | memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1)); |
|---|
| 233 | 252 | break; |
|---|
| 234 | 253 | case 2: set->sig[1] = -1; |
|---|
| 254 | + break; |
|---|
| 235 | 255 | case 1: ; |
|---|
| 236 | 256 | } |
|---|
| 237 | 257 | } |
|---|
| .. | .. |
|---|
| 245 | 265 | } |
|---|
| 246 | 266 | |
|---|
| 247 | 267 | extern void flush_sigqueue(struct sigpending *queue); |
|---|
| 248 | | -extern void flush_task_sigqueue(struct task_struct *tsk); |
|---|
| 249 | 268 | |
|---|
| 250 | 269 | /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */ |
|---|
| 251 | 270 | static inline int valid_signal(unsigned long sig) |
|---|
| .. | .. |
|---|
| 258 | 277 | enum pid_type; |
|---|
| 259 | 278 | |
|---|
| 260 | 279 | extern int next_signal(struct sigpending *pending, sigset_t *mask); |
|---|
| 261 | | -extern int do_send_sig_info(int sig, struct siginfo *info, |
|---|
| 280 | +extern int do_send_sig_info(int sig, struct kernel_siginfo *info, |
|---|
| 262 | 281 | struct task_struct *p, enum pid_type type); |
|---|
| 263 | | -extern int group_send_sig_info(int sig, struct siginfo *info, |
|---|
| 282 | +extern int group_send_sig_info(int sig, struct kernel_siginfo *info, |
|---|
| 264 | 283 | struct task_struct *p, enum pid_type type); |
|---|
| 265 | | -extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); |
|---|
| 284 | +extern int __group_send_sig_info(int, struct kernel_siginfo *, struct task_struct *); |
|---|
| 266 | 285 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
|---|
| 267 | 286 | extern void set_current_blocked(sigset_t *); |
|---|
| 268 | 287 | extern void __set_current_blocked(const sigset_t *); |
|---|
| .. | .. |
|---|
| 392 | 411 | #endif |
|---|
| 393 | 412 | |
|---|
| 394 | 413 | #define siginmask(sig, mask) \ |
|---|
| 395 | | - ((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) |
|---|
| 414 | + ((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) |
|---|
| 396 | 415 | |
|---|
| 397 | 416 | #define SIG_KERNEL_ONLY_MASK (\ |
|---|
| 398 | 417 | rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP)) |
|---|
| .. | .. |
|---|
| 435 | 454 | int restore_altstack(const stack_t __user *); |
|---|
| 436 | 455 | int __save_altstack(stack_t __user *, unsigned long); |
|---|
| 437 | 456 | |
|---|
| 438 | | -#define save_altstack_ex(uss, sp) do { \ |
|---|
| 457 | +#define unsafe_save_altstack(uss, sp, label) do { \ |
|---|
| 439 | 458 | stack_t __user *__uss = uss; \ |
|---|
| 440 | 459 | struct task_struct *t = current; \ |
|---|
| 441 | | - put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ |
|---|
| 442 | | - put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ |
|---|
| 443 | | - put_user_ex(t->sas_ss_size, &__uss->ss_size); \ |
|---|
| 460 | + unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \ |
|---|
| 461 | + unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \ |
|---|
| 462 | + unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \ |
|---|
| 444 | 463 | if (t->sas_ss_flags & SS_AUTODISARM) \ |
|---|
| 445 | 464 | sas_ss_reset(t); \ |
|---|
| 446 | 465 | } while (0); |
|---|
| .. | .. |
|---|
| 450 | 469 | extern void render_sigset_t(struct seq_file *, const char *, sigset_t *); |
|---|
| 451 | 470 | #endif |
|---|
| 452 | 471 | |
|---|
| 472 | +#ifndef arch_untagged_si_addr |
|---|
| 473 | +/* |
|---|
| 474 | + * Given a fault address and a signal and si_code which correspond to the |
|---|
| 475 | + * _sigfault union member, returns the address that must appear in si_addr if |
|---|
| 476 | + * the signal handler does not have SA_EXPOSE_TAGBITS enabled in sa_flags. |
|---|
| 477 | + */ |
|---|
| 478 | +static inline void __user *arch_untagged_si_addr(void __user *addr, |
|---|
| 479 | + unsigned long sig, |
|---|
| 480 | + unsigned long si_code) |
|---|
| 481 | +{ |
|---|
| 482 | + return addr; |
|---|
| 483 | +} |
|---|
| 484 | +#endif |
|---|
| 485 | + |
|---|
| 453 | 486 | #endif /* _LINUX_SIGNAL_H */ |
|---|