diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 9 | ||||
-rw-r--r-- | kernel/fork.c | 8 | ||||
-rw-r--r-- | kernel/signal.c | 22 | ||||
-rw-r--r-- | kernel/sys_ni.c | 3 |
4 files changed, 37 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index e93691e9b325..c6d14b8008dd 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/pid_namespace.h> | 24 | #include <linux/pid_namespace.h> |
25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
26 | #include <linux/profile.h> | 26 | #include <linux/profile.h> |
27 | #include <linux/signalfd.h> | ||
27 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
28 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
29 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
@@ -83,6 +84,14 @@ static void __exit_signal(struct task_struct *tsk) | |||
83 | sighand = rcu_dereference(tsk->sighand); | 84 | sighand = rcu_dereference(tsk->sighand); |
84 | spin_lock(&sighand->siglock); | 85 | spin_lock(&sighand->siglock); |
85 | 86 | ||
87 | /* | ||
88 | * Notify that this sighand has been detached. This must | ||
89 | * be called with the tsk->sighand lock held. Also, this | ||
90 | * access tsk->sighand internally, so it must be called | ||
91 | * before tsk->sighand is reset. | ||
92 | */ | ||
93 | signalfd_detach_locked(tsk); | ||
94 | |||
86 | posix_cpu_timers_exit(tsk); | 95 | posix_cpu_timers_exit(tsk); |
87 | if (atomic_dec_and_test(&sig->count)) | 96 | if (atomic_dec_and_test(&sig->count)) |
88 | posix_cpu_timers_exit_group(tsk); | 97 | posix_cpu_timers_exit_group(tsk); |
diff --git a/kernel/fork.c b/kernel/fork.c index 083bf8953ce8..49530e40ea8b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1422,12 +1422,15 @@ long do_fork(unsigned long clone_flags, | |||
1422 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 | 1422 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 |
1423 | #endif | 1423 | #endif |
1424 | 1424 | ||
1425 | static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long flags) | 1425 | static void sighand_ctor(void *data, struct kmem_cache *cachep, |
1426 | unsigned long flags) | ||
1426 | { | 1427 | { |
1427 | struct sighand_struct *sighand = data; | 1428 | struct sighand_struct *sighand = data; |
1428 | 1429 | ||
1429 | if (flags & SLAB_CTOR_CONSTRUCTOR) | 1430 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
1430 | spin_lock_init(&sighand->siglock); | 1431 | spin_lock_init(&sighand->siglock); |
1432 | INIT_LIST_HEAD(&sighand->signalfd_list); | ||
1433 | } | ||
1431 | } | 1434 | } |
1432 | 1435 | ||
1433 | void __init proc_caches_init(void) | 1436 | void __init proc_caches_init(void) |
@@ -1453,7 +1456,6 @@ void __init proc_caches_init(void) | |||
1453 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 1456 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
1454 | } | 1457 | } |
1455 | 1458 | ||
1456 | |||
1457 | /* | 1459 | /* |
1458 | * Check constraints on flags passed to the unshare system call and | 1460 | * Check constraints on flags passed to the unshare system call and |
1459 | * force unsharing of additional process context as appropriate. | 1461 | * force unsharing of additional process context as appropriate. |
diff --git a/kernel/signal.c b/kernel/signal.c index 2ac3a668d9dd..34b7d6abce8f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
22 | #include <linux/ptrace.h> | 22 | #include <linux/ptrace.h> |
23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
24 | #include <linux/signalfd.h> | ||
24 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
25 | #include <linux/freezer.h> | 26 | #include <linux/freezer.h> |
26 | #include <linux/pid_namespace.h> | 27 | #include <linux/pid_namespace.h> |
@@ -113,8 +114,7 @@ void recalc_sigpending(void) | |||
113 | 114 | ||
114 | /* Given the mask, find the first available signal that should be serviced. */ | 115 | /* Given the mask, find the first available signal that should be serviced. */ |
115 | 116 | ||
116 | static int | 117 | int next_signal(struct sigpending *pending, sigset_t *mask) |
117 | next_signal(struct sigpending *pending, sigset_t *mask) | ||
118 | { | 118 | { |
119 | unsigned long i, *s, *m, x; | 119 | unsigned long i, *s, *m, x; |
120 | int sig = 0; | 120 | int sig = 0; |
@@ -630,6 +630,12 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
630 | int ret = 0; | 630 | int ret = 0; |
631 | 631 | ||
632 | /* | 632 | /* |
633 | * Deliver the signal to listening signalfds. This must be called | ||
634 | * with the sighand lock held. | ||
635 | */ | ||
636 | signalfd_notify(t, sig); | ||
637 | |||
638 | /* | ||
633 | * fast-pathed signals for kernel-internal things like SIGSTOP | 639 | * fast-pathed signals for kernel-internal things like SIGSTOP |
634 | * or SIGKILL. | 640 | * or SIGKILL. |
635 | */ | 641 | */ |
@@ -1280,6 +1286,11 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) | |||
1280 | ret = 1; | 1286 | ret = 1; |
1281 | goto out; | 1287 | goto out; |
1282 | } | 1288 | } |
1289 | /* | ||
1290 | * Deliver the signal to listening signalfds. This must be called | ||
1291 | * with the sighand lock held. | ||
1292 | */ | ||
1293 | signalfd_notify(p, sig); | ||
1283 | 1294 | ||
1284 | list_add_tail(&q->list, &p->pending.list); | 1295 | list_add_tail(&q->list, &p->pending.list); |
1285 | sigaddset(&p->pending.signal, sig); | 1296 | sigaddset(&p->pending.signal, sig); |
@@ -1323,6 +1334,11 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) | |||
1323 | q->info.si_overrun++; | 1334 | q->info.si_overrun++; |
1324 | goto out; | 1335 | goto out; |
1325 | } | 1336 | } |
1337 | /* | ||
1338 | * Deliver the signal to listening signalfds. This must be called | ||
1339 | * with the sighand lock held. | ||
1340 | */ | ||
1341 | signalfd_notify(p, sig); | ||
1326 | 1342 | ||
1327 | /* | 1343 | /* |
1328 | * Put this signal on the shared-pending queue. | 1344 | * Put this signal on the shared-pending queue. |
@@ -1983,6 +1999,8 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) | |||
1983 | /* | 1999 | /* |
1984 | * If you change siginfo_t structure, please be sure | 2000 | * If you change siginfo_t structure, please be sure |
1985 | * this code is fixed accordingly. | 2001 | * this code is fixed accordingly. |
2002 | * Please remember to update the signalfd_copyinfo() function | ||
2003 | * inside fs/signalfd.c too, in case siginfo_t changes. | ||
1986 | * It should never copy any pad contained in the structure | 2004 | * It should never copy any pad contained in the structure |
1987 | * to avoid security leaks, but must copy the generic | 2005 | * to avoid security leaks, but must copy the generic |
1988 | * 3 ints plus the relevant union member. | 2006 | * 3 ints plus the relevant union member. |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index d7306d0f3dfc..807e9bb8fcdb 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -141,3 +141,6 @@ cond_syscall(compat_sys_migrate_pages); | |||
141 | cond_syscall(sys_bdflush); | 141 | cond_syscall(sys_bdflush); |
142 | cond_syscall(sys_ioprio_set); | 142 | cond_syscall(sys_ioprio_set); |
143 | cond_syscall(sys_ioprio_get); | 143 | cond_syscall(sys_ioprio_get); |
144 | |||
145 | /* New file descriptors */ | ||
146 | cond_syscall(sys_signalfd); | ||