projects
/
linux-drm-fsl-dcu.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[PATCH] sysctl warning fix
[linux-drm-fsl-dcu.git]
/
kernel
/
signal.c
diff --git
a/kernel/signal.c
b/kernel/signal.c
index 7ed8d5304bec2d2c9e51099f5c66ff304d40946a..ea4632bd40a0edb6238232ed42ffb5ebb3d68146 100644
(file)
--- a/
kernel/signal.c
+++ b/
kernel/signal.c
@@
-23,6
+23,10
@@
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/capability.h>
+#include <linux/freezer.h>
+#include <linux/pid_namespace.h>
+#include <linux/nsproxy.h>
+
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@
-33,7
+37,7
@@
* SLAB caches for signal bits.
*/
* SLAB caches for signal bits.
*/
-static
kmem_cache_t
*sigqueue_cachep;
+static
struct kmem_cache
*sigqueue_cachep;
/*
* In POSIX a signal is sent either to a specific thread (Linux task)
/*
* In POSIX a signal is sent either to a specific thread (Linux task)
@@
-267,18
+271,25
@@
static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
int override_rlimit)
{
struct sigqueue *q = NULL;
int override_rlimit)
{
struct sigqueue *q = NULL;
+ struct user_struct *user;
- atomic_inc(&t->user->sigpending);
+ /*
+ * In order to avoid problems with "switch_user()", we want to make
+ * sure that the compiler doesn't re-load "t->user"
+ */
+ user = t->user;
+ barrier();
+ atomic_inc(&user->sigpending);
if (override_rlimit ||
if (override_rlimit ||
- atomic_read(&
t->
user->sigpending) <=
+ atomic_read(&user->sigpending) <=
t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
q = kmem_cache_alloc(sigqueue_cachep, flags);
if (unlikely(q == NULL)) {
t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
q = kmem_cache_alloc(sigqueue_cachep, flags);
if (unlikely(q == NULL)) {
- atomic_dec(&
t->
user->sigpending);
+ atomic_dec(&user->sigpending);
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
- q->user = get_uid(
t->
user);
+ q->user = get_uid(user);
}
return(q);
}
}
return(q);
}
@@
-575,7
+586,7
@@
static int check_kill_permission(int sig, struct siginfo *info,
error = -EPERM;
if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
error = -EPERM;
if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
- (
current->signal->session != t->signal->session
))
+ (
process_session(current) != process_session(t)
))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
@@
-1108,26
+1119,24
@@
kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
{
int error;
int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
{
int error;
- int acquired_tasklist_lock = 0;
struct task_struct *p;
rcu_read_lock();
struct task_struct *p;
rcu_read_lock();
- if (unlikely(sig_needs_tasklist(sig)))
{
+ if (unlikely(sig_needs_tasklist(sig)))
read_lock(&tasklist_lock);
read_lock(&tasklist_lock);
- acquired_tasklist_lock = 1;
- }
+
p = pid_task(pid, PIDTYPE_PID);
error = -ESRCH;
if (p)
error = group_send_sig_info(sig, info, p);
p = pid_task(pid, PIDTYPE_PID);
error = -ESRCH;
if (p)
error = group_send_sig_info(sig, info, p);
- if (unlikely(acquired_tasklist_lock))
+
+ if (unlikely(sig_needs_tasklist(sig)))
read_unlock(&tasklist_lock);
rcu_read_unlock();
return error;
}
read_unlock(&tasklist_lock);
rcu_read_unlock();
return error;
}
-int
-kill_proc_info(int sig, struct siginfo *info, pid_t pid)
+static int kill_proc_info(int sig, struct siginfo *info, pid_t pid)
{
int error;
rcu_read_lock();
{
int error;
rcu_read_lock();
@@
-1695,7
+1704,9
@@
finish_stop(int stop_count)
read_unlock(&tasklist_lock);
}
read_unlock(&tasklist_lock);
}
- schedule();
+ do {
+ schedule();
+ } while (try_to_freeze());
/*
* Now we don't run again until continued.
*/
/*
* Now we don't run again until continued.
*/
@@
-1870,8
+1881,12
@@
relock:
if (sig_kernel_ignore(signr)) /* Default is nothing. */
continue;
if (sig_kernel_ignore(signr)) /* Default is nothing. */
continue;
- /* Init gets no signals it doesn't want. */
- if (current == child_reaper)
+ /*
+ * Init of a pid space gets no signals it doesn't want from
+ * within that pid space. It can of course get signals from
+ * its parent pid space.
+ */
+ if (current == child_reaper(current))
continue;
if (sig_kernel_stop(signr)) {
continue;
if (sig_kernel_stop(signr)) {