summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/kmod.c10
-rw-r--r--kernel/ksyms.c3
-rw-r--r--kernel/sched.c5
-rw-r--r--kernel/signal.c8
-rw-r--r--kernel/sys.c23
-rw-r--r--kernel/time.c15
-rw-r--r--kernel/user.c17
8 files changed, 55 insertions, 28 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 729e93bff8e4..de34ed9091f5 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -249,7 +249,7 @@ void reparent_to_init(void)
/* signals? */
security_task_reparent_to_init(current);
memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
- current->user = INIT_USER;
+ switch_uid(INIT_USER);
write_unlock_irq(&tasklist_lock);
}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 1930367d3736..257634f94652 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -121,15 +121,7 @@ int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
if (curtask->files->fd[i]) close(i);
}
- /* Drop the "current user" thing */
- {
- struct user_struct *user = curtask->user;
- curtask->user = INIT_USER;
- atomic_inc(&INIT_USER->__count);
- atomic_inc(&INIT_USER->processes);
- atomic_dec(&user->processes);
- free_uid(user);
- }
+ switch_uid(INIT_USER);
/* Give kmod all effective privileges.. */
curtask->euid = curtask->fsuid = 0;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 0f2b487d0789..f0503df9fe3d 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -490,6 +490,9 @@ EXPORT_SYMBOL(xtime);
EXPORT_SYMBOL(xtime_lock);
EXPORT_SYMBOL(do_gettimeofday);
EXPORT_SYMBOL(do_settimeofday);
+#if (BITS_PER_LONG < 64)
+EXPORT_SYMBOL(get_jiffies_64);
+#endif
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
EXPORT_SYMBOL(__might_sleep);
#endif
diff --git a/kernel/sched.c b/kernel/sched.c
index 3e967ec6814f..a501326ed2dc 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -506,7 +506,8 @@ int wake_up_state(task_t *p, unsigned int state)
*/
void wake_up_forked_process(task_t * p)
{
- runqueue_t *rq = this_rq_lock();
+ unsigned long flags;
+ runqueue_t *rq = task_rq_lock(current, &flags);
p->state = TASK_RUNNING;
if (!rt_task(p)) {
@@ -522,7 +523,7 @@ void wake_up_forked_process(task_t * p)
set_task_cpu(p, smp_processor_id());
activate_task(p, rq);
- rq_unlock(rq);
+ task_rq_unlock(rq, &flags);
}
/*
diff --git a/kernel/signal.c b/kernel/signal.c
index a4d6618f77d0..b43102e63a8d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -619,6 +619,7 @@ static void handle_stop_signal(int sig, struct task_struct *p)
rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
t = p;
do {
+ unsigned int state;
rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
/*
@@ -635,9 +636,12 @@ static void handle_stop_signal(int sig, struct task_struct *p)
* Wake up the stopped thread _after_ setting
* TIF_SIGPENDING
*/
- if (!sigismember(&t->blocked, SIGCONT))
+ state = TASK_STOPPED;
+ if (!sigismember(&t->blocked, SIGCONT)) {
set_tsk_thread_flag(t, TIF_SIGPENDING);
- wake_up_state(t, TASK_STOPPED);
+ state |= TASK_INTERRUPTIBLE;
+ }
+ wake_up_state(t, state);
t = next_thread(t);
} while (t != p);
diff --git a/kernel/sys.c b/kernel/sys.c
index 9404304eba74..afa6d2fc1372 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -561,19 +561,12 @@ asmlinkage long sys_setgid(gid_t gid)
static int set_user(uid_t new_ruid, int dumpclear)
{
- struct user_struct *new_user, *old_user;
+ struct user_struct *new_user;
- /* What if a process setreuid()'s and this brings the
- * new uid over his NPROC rlimit? We can check this now
- * cheaply with the new uid cache, so if it matters
- * we should be checking for it. -DaveM
- */
new_user = alloc_uid(new_ruid);
if (!new_user)
return -EAGAIN;
- old_user = current->user;
- atomic_dec(&old_user->processes);
- atomic_inc(&new_user->processes);
+ switch_uid(new_user);
if(dumpclear)
{
@@ -581,8 +574,6 @@ static int set_user(uid_t new_ruid, int dumpclear)
wmb();
}
current->uid = new_ruid;
- current->user = new_user;
- free_uid(old_user);
return 0;
}
@@ -916,6 +907,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
p = find_task_by_pid(pid);
if (!p)
goto out;
+
err = -EINVAL;
if (!thread_group_leader(p))
goto out;
@@ -927,11 +919,16 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
err = -EACCES;
if (p->did_exec)
goto out;
- } else if (p != current)
- goto out;
+ } else {
+ err = -ESRCH;
+ if (p != current)
+ goto out;
+ }
+
err = -EPERM;
if (p->leader)
goto out;
+
if (pgid != pid) {
struct task_struct *p;
struct pid *pid;
diff --git a/kernel/time.c b/kernel/time.c
index c8c8a10eae1f..4ecc0a3b2ac1 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -27,7 +27,6 @@
#include <linux/timex.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
-
#include <asm/uaccess.h>
/*
@@ -416,3 +415,17 @@ struct timespec current_kernel_time(void)
return now;
}
+
+#if (BITS_PER_LONG < 64)
+u64 get_jiffies_64(void)
+{
+ unsigned long seq;
+ u64 ret;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+ ret = jiffies_64;
+ } while (read_seqretry(&xtime_lock, seq));
+ return ret;
+}
+#endif
diff --git a/kernel/user.c b/kernel/user.c
index 0704b2aad9c5..592680d8cc68 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -116,6 +116,23 @@ struct user_struct * alloc_uid(uid_t uid)
return up;
}
+void switch_uid(struct user_struct *new_user)
+{
+ struct user_struct *old_user;
+
+ /* What if a process setreuid()'s and this brings the
+ * new uid over his NPROC rlimit? We can check this now
+ * cheaply with the new uid cache, so if it matters
+ * we should be checking for it. -DaveM
+ */
+ old_user = current->user;
+ atomic_inc(&new_user->__count);
+ atomic_inc(&new_user->processes);
+ atomic_dec(&old_user->processes);
+ current->user = new_user;
+ free_uid(old_user);
+}
+
static int __init uid_cache_init(void)
{