aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 21:50:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 21:50:11 -0500
commit9e2d59ad580d590134285f361a0e80f0e98c0207 (patch)
treef3232be75781484193413f32ec82c21f6d8eb76e /include/linux
parent5ce1a70e2f00f0bce0cab57f798ca354b9496169 (diff)
parent235b80226b986dabcbba844968f7807866bd0bfe (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull signal handling cleanups from Al Viro: "This is the first pile; another one will come a bit later and will contain SYSCALL_DEFINE-related patches. - a bunch of signal-related syscalls (both native and compat) unified. - a bunch of compat syscalls switched to COMPAT_SYSCALL_DEFINE (fixing several potential problems with missing argument validation, while we are at it) - a lot of now-pointless wrappers killed - a couple of architectures (cris and hexagon) forgot to save altstack settings into sigframe, even though they used the (uninitialized) values in sigreturn; fixed. - microblaze fixes for delivery of multiple signals arriving at once - saner set of helpers for signal delivery introduced, several architectures switched to using those." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (143 commits) x86: convert to ksignal sparc: convert to ksignal arm: switch to struct ksignal * passing alpha: pass k_sigaction and siginfo_t using ksignal pointer burying unused conditionals make do_sigaltstack() static arm64: switch to generic old sigaction() (compat-only) arm64: switch to generic compat rt_sigaction() arm64: switch compat to generic old sigsuspend arm64: switch to generic compat rt_sigqueueinfo() arm64: switch to generic compat rt_sigpending() arm64: switch to generic compat rt_sigprocmask() arm64: switch to generic sigaltstack sparc: switch to generic old sigsuspend sparc: COMPAT_SYSCALL_DEFINE does all sign-extension as well as SYSCALL_DEFINE sparc: kill sign-extending wrappers for native syscalls kill sparc32_open() sparc: switch to use of generic old sigaction sparc: switch sys_compat_rt_sigaction() to COMPAT_SYSCALL_DEFINE mips: switch to generic sys_fork() and sys_clone() ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/compat.h50
-rw-r--r--include/linux/sched.h12
-rw-r--r--include/linux/signal.h52
-rw-r--r--include/linux/syscalls.h25
4 files changed, 126 insertions, 13 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h
index dec7e2d18875..de095b0462a7 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -68,7 +68,6 @@
68#ifndef compat_user_stack_pointer 68#ifndef compat_user_stack_pointer
69#define compat_user_stack_pointer() current_user_stack_pointer() 69#define compat_user_stack_pointer() current_user_stack_pointer()
70#endif 70#endif
71#ifdef CONFIG_GENERIC_SIGALTSTACK
72#ifndef compat_sigaltstack /* we'll need that for MIPS */ 71#ifndef compat_sigaltstack /* we'll need that for MIPS */
73typedef struct compat_sigaltstack { 72typedef struct compat_sigaltstack {
74 compat_uptr_t ss_sp; 73 compat_uptr_t ss_sp;
@@ -76,7 +75,6 @@ typedef struct compat_sigaltstack {
76 compat_size_t ss_size; 75 compat_size_t ss_size;
77} compat_stack_t; 76} compat_stack_t;
78#endif 77#endif
79#endif
80 78
81#define compat_jiffies_to_clock_t(x) \ 79#define compat_jiffies_to_clock_t(x) \
82 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) 80 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
@@ -142,6 +140,20 @@ typedef struct {
142 compat_sigset_word sig[_COMPAT_NSIG_WORDS]; 140 compat_sigset_word sig[_COMPAT_NSIG_WORDS];
143} compat_sigset_t; 141} compat_sigset_t;
144 142
143struct compat_sigaction {
144#ifndef __ARCH_HAS_ODD_SIGACTION
145 compat_uptr_t sa_handler;
146 compat_ulong_t sa_flags;
147#else
148 compat_ulong_t sa_flags;
149 compat_uptr_t sa_handler;
150#endif
151#ifdef __ARCH_HAS_SA_RESTORER
152 compat_uptr_t sa_restorer;
153#endif
154 compat_sigset_t sa_mask __packed;
155};
156
145/* 157/*
146 * These functions operate strictly on struct compat_time* 158 * These functions operate strictly on struct compat_time*
147 */ 159 */
@@ -283,6 +295,15 @@ struct compat_robust_list_head {
283 compat_uptr_t list_op_pending; 295 compat_uptr_t list_op_pending;
284}; 296};
285 297
298#ifdef CONFIG_COMPAT_OLD_SIGACTION
299struct compat_old_sigaction {
300 compat_uptr_t sa_handler;
301 compat_old_sigset_t sa_mask;
302 compat_ulong_t sa_flags;
303 compat_uptr_t sa_restorer;
304};
305#endif
306
286struct compat_statfs; 307struct compat_statfs;
287struct compat_statfs64; 308struct compat_statfs64;
288struct compat_old_linux_dirent; 309struct compat_old_linux_dirent;
@@ -367,6 +388,11 @@ int get_compat_sigevent(struct sigevent *event,
367 const struct compat_sigevent __user *u_event); 388 const struct compat_sigevent __user *u_event);
368long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig, 389long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
369 struct compat_siginfo __user *uinfo); 390 struct compat_siginfo __user *uinfo);
391#ifdef CONFIG_COMPAT_OLD_SIGACTION
392asmlinkage long compat_sys_sigaction(int sig,
393 const struct compat_old_sigaction __user *act,
394 struct compat_old_sigaction __user *oact);
395#endif
370 396
371static inline int compat_timeval_compare(struct compat_timeval *lhs, 397static inline int compat_timeval_compare(struct compat_timeval *lhs,
372 struct compat_timeval *rhs) 398 struct compat_timeval *rhs)
@@ -401,7 +427,8 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
401asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); 427asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
402 428
403extern int compat_printk(const char *fmt, ...); 429extern int compat_printk(const char *fmt, ...);
404extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); 430extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
431extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
405 432
406asmlinkage long compat_sys_migrate_pages(compat_pid_t pid, 433asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
407 compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes, 434 compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
@@ -503,7 +530,7 @@ asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
503 unsigned int nr_segs, unsigned int flags); 530 unsigned int nr_segs, unsigned int flags);
504asmlinkage long compat_sys_open(const char __user *filename, int flags, 531asmlinkage long compat_sys_open(const char __user *filename, int flags,
505 umode_t mode); 532 umode_t mode);
506asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, 533asmlinkage long compat_sys_openat(int dfd, const char __user *filename,
507 int flags, umode_t mode); 534 int flags, umode_t mode);
508asmlinkage long compat_sys_open_by_handle_at(int mountdirfd, 535asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
509 struct file_handle __user *handle, 536 struct file_handle __user *handle,
@@ -592,6 +619,19 @@ asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
592 struct compat_timespec __user *uts, compat_size_t sigsetsize); 619 struct compat_timespec __user *uts, compat_size_t sigsetsize);
593asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, 620asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
594 compat_size_t sigsetsize); 621 compat_size_t sigsetsize);
622asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
623 compat_sigset_t __user *oset,
624 compat_size_t sigsetsize);
625asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
626 compat_size_t sigsetsize);
627#ifndef CONFIG_ODD_RT_SIGACTION
628asmlinkage long compat_sys_rt_sigaction(int,
629 const struct compat_sigaction __user *,
630 struct compat_sigaction __user *,
631 compat_size_t);
632#endif
633asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
634 struct compat_siginfo __user *uinfo);
595asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 635asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
596asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 636asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
597 unsigned long arg); 637 unsigned long arg);
@@ -642,13 +682,11 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
642 682
643asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 683asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
644 compat_off_t __user *offset, compat_size_t count); 684 compat_off_t __user *offset, compat_size_t count);
645#ifdef CONFIG_GENERIC_SIGALTSTACK
646asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, 685asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
647 compat_stack_t __user *uoss_ptr); 686 compat_stack_t __user *uoss_ptr);
648 687
649int compat_restore_altstack(const compat_stack_t __user *uss); 688int compat_restore_altstack(const compat_stack_t __user *uss);
650int __compat_save_altstack(compat_stack_t __user *, unsigned long); 689int __compat_save_altstack(compat_stack_t __user *, unsigned long);
651#endif
652 690
653asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, 691asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
654 struct compat_timespec __user *interval); 692 struct compat_timespec __user *interval);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c2182b53dace..0655570c67eb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2182,7 +2182,6 @@ extern struct sigqueue *sigqueue_alloc(void);
2182extern void sigqueue_free(struct sigqueue *); 2182extern void sigqueue_free(struct sigqueue *);
2183extern int send_sigqueue(struct sigqueue *, struct task_struct *, int group); 2183extern int send_sigqueue(struct sigqueue *, struct task_struct *, int group);
2184extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); 2184extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
2185extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
2186 2185
2187static inline void restore_saved_sigmask(void) 2186static inline void restore_saved_sigmask(void)
2188{ 2187{
@@ -2228,6 +2227,17 @@ static inline int sas_ss_flags(unsigned long sp)
2228 : on_sig_stack(sp) ? SS_ONSTACK : 0); 2227 : on_sig_stack(sp) ? SS_ONSTACK : 0);
2229} 2228}
2230 2229
2230static inline unsigned long sigsp(unsigned long sp, struct ksignal *ksig)
2231{
2232 if (unlikely((ksig->ka.sa.sa_flags & SA_ONSTACK)) && ! sas_ss_flags(sp))
2233#ifdef CONFIG_STACK_GROWSUP
2234 return current->sas_ss_sp;
2235#else
2236 return current->sas_ss_sp + current->sas_ss_size;
2237#endif
2238 return sp;
2239}
2240
2231/* 2241/*
2232 * Routines for handling mm_structs 2242 * Routines for handling mm_structs
2233 */ 2243 */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 0a89ffc48466..a2dcb94ea49d 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -241,9 +241,6 @@ extern int do_send_sig_info(int sig, struct siginfo *info,
241 struct task_struct *p, bool group); 241 struct task_struct *p, bool group);
242extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); 242extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
243extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); 243extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
244extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
245 siginfo_t *info);
246extern long do_sigpending(void __user *, unsigned long);
247extern int do_sigtimedwait(const sigset_t *, siginfo_t *, 244extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
248 const struct timespec *); 245 const struct timespec *);
249extern int sigprocmask(int, sigset_t *, sigset_t *); 246extern int sigprocmask(int, sigset_t *, sigset_t *);
@@ -252,10 +249,59 @@ extern void __set_current_blocked(const sigset_t *);
252extern int show_unhandled_signals; 249extern int show_unhandled_signals;
253extern int sigsuspend(sigset_t *); 250extern int sigsuspend(sigset_t *);
254 251
252struct sigaction {
253#ifndef __ARCH_HAS_ODD_SIGACTION
254 __sighandler_t sa_handler;
255 unsigned long sa_flags;
256#else
257 unsigned long sa_flags;
258 __sighandler_t sa_handler;
259#endif
260#ifdef __ARCH_HAS_SA_RESTORER
261 __sigrestore_t sa_restorer;
262#endif
263 sigset_t sa_mask; /* mask last for extensibility */
264};
265
266struct k_sigaction {
267 struct sigaction sa;
268#ifdef __ARCH_HAS_KA_RESTORER
269 __sigrestore_t ka_restorer;
270#endif
271};
272
273#ifdef CONFIG_OLD_SIGACTION
274struct old_sigaction {
275 __sighandler_t sa_handler;
276 old_sigset_t sa_mask;
277 unsigned long sa_flags;
278 __sigrestore_t sa_restorer;
279};
280#endif
281
282struct ksignal {
283 struct k_sigaction ka;
284 siginfo_t info;
285 int sig;
286};
287
255extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); 288extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
289extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
256extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping); 290extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
257extern void exit_signals(struct task_struct *tsk); 291extern void exit_signals(struct task_struct *tsk);
258 292
293/*
294 * Eventually that'll replace get_signal_to_deliver(); macro for now,
295 * to avoid nastiness with include order.
296 */
297#define get_signal(ksig) \
298({ \
299 struct ksignal *p = (ksig); \
300 p->sig = get_signal_to_deliver(&p->info, &p->ka, \
301 signal_pt_regs(), NULL);\
302 p->sig > 0; \
303})
304
259extern struct kmem_cache *sighand_cachep; 305extern struct kmem_cache *sighand_cachep;
260 306
261int unhandled_signal(struct task_struct *tsk, int sig); 307int unhandled_signal(struct task_struct *tsk, int sig);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 45e2db270255..313a8e0a6553 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -68,11 +68,11 @@ struct sigaltstack;
68#include <linux/types.h> 68#include <linux/types.h>
69#include <linux/aio_abi.h> 69#include <linux/aio_abi.h>
70#include <linux/capability.h> 70#include <linux/capability.h>
71#include <linux/signal.h>
71#include <linux/list.h> 72#include <linux/list.h>
72#include <linux/bug.h> 73#include <linux/bug.h>
73#include <linux/sem.h> 74#include <linux/sem.h>
74#include <asm/siginfo.h> 75#include <asm/siginfo.h>
75#include <asm/signal.h>
76#include <linux/unistd.h> 76#include <linux/unistd.h>
77#include <linux/quota.h> 77#include <linux/quota.h>
78#include <linux/key.h> 78#include <linux/key.h>
@@ -300,10 +300,8 @@ asmlinkage long sys_personality(unsigned int personality);
300asmlinkage long sys_sigpending(old_sigset_t __user *set); 300asmlinkage long sys_sigpending(old_sigset_t __user *set);
301asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, 301asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set,
302 old_sigset_t __user *oset); 302 old_sigset_t __user *oset);
303#ifdef CONFIG_GENERIC_SIGALTSTACK
304asmlinkage long sys_sigaltstack(const struct sigaltstack __user *uss, 303asmlinkage long sys_sigaltstack(const struct sigaltstack __user *uss,
305 struct sigaltstack __user *uoss); 304 struct sigaltstack __user *uoss);
306#endif
307 305
308asmlinkage long sys_getitimer(int which, struct itimerval __user *value); 306asmlinkage long sys_getitimer(int which, struct itimerval __user *value);
309asmlinkage long sys_setitimer(int which, 307asmlinkage long sys_setitimer(int which,
@@ -377,6 +375,27 @@ asmlinkage long sys_init_module(void __user *umod, unsigned long len,
377asmlinkage long sys_delete_module(const char __user *name_user, 375asmlinkage long sys_delete_module(const char __user *name_user,
378 unsigned int flags); 376 unsigned int flags);
379 377
378#ifdef CONFIG_OLD_SIGSUSPEND
379asmlinkage long sys_sigsuspend(old_sigset_t mask);
380#endif
381
382#ifdef CONFIG_OLD_SIGSUSPEND3
383asmlinkage long sys_sigsuspend(int unused1, int unused2, old_sigset_t mask);
384#endif
385
386asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
387
388#ifdef CONFIG_OLD_SIGACTION
389asmlinkage long sys_sigaction(int, const struct old_sigaction __user *,
390 struct old_sigaction __user *);
391#endif
392
393#ifndef CONFIG_ODD_RT_SIGACTION
394asmlinkage long sys_rt_sigaction(int,
395 const struct sigaction __user *,
396 struct sigaction __user *,
397 size_t);
398#endif
380asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set, 399asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set,
381 sigset_t __user *oset, size_t sigsetsize); 400 sigset_t __user *oset, size_t sigsetsize);
382asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize); 401asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize);