aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c10
-rw-r--r--fs/proc/base.c8
-rw-r--r--include/linux/init_task.h4
-rw-r--r--include/linux/sched.h7
-rw-r--r--include/linux/tracehook.h2
-rw-r--r--kernel/cred.c4
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/ptrace.c4
8 files changed, 21 insertions, 20 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 3aa75b8888a1..9722909c4d88 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1083,14 +1083,14 @@ EXPORT_SYMBOL(setup_new_exec);
1083 */ 1083 */
1084int prepare_bprm_creds(struct linux_binprm *bprm) 1084int prepare_bprm_creds(struct linux_binprm *bprm)
1085{ 1085{
1086 if (mutex_lock_interruptible(&current->cred_guard_mutex)) 1086 if (mutex_lock_interruptible(&current->signal->cred_guard_mutex))
1087 return -ERESTARTNOINTR; 1087 return -ERESTARTNOINTR;
1088 1088
1089 bprm->cred = prepare_exec_creds(); 1089 bprm->cred = prepare_exec_creds();
1090 if (likely(bprm->cred)) 1090 if (likely(bprm->cred))
1091 return 0; 1091 return 0;
1092 1092
1093 mutex_unlock(&current->cred_guard_mutex); 1093 mutex_unlock(&current->signal->cred_guard_mutex);
1094 return -ENOMEM; 1094 return -ENOMEM;
1095} 1095}
1096 1096
@@ -1098,7 +1098,7 @@ void free_bprm(struct linux_binprm *bprm)
1098{ 1098{
1099 free_arg_pages(bprm); 1099 free_arg_pages(bprm);
1100 if (bprm->cred) { 1100 if (bprm->cred) {
1101 mutex_unlock(&current->cred_guard_mutex); 1101 mutex_unlock(&current->signal->cred_guard_mutex);
1102 abort_creds(bprm->cred); 1102 abort_creds(bprm->cred);
1103 } 1103 }
1104 kfree(bprm); 1104 kfree(bprm);
@@ -1119,13 +1119,13 @@ void install_exec_creds(struct linux_binprm *bprm)
1119 * credentials; any time after this it may be unlocked. 1119 * credentials; any time after this it may be unlocked.
1120 */ 1120 */
1121 security_bprm_committed_creds(bprm); 1121 security_bprm_committed_creds(bprm);
1122 mutex_unlock(&current->cred_guard_mutex); 1122 mutex_unlock(&current->signal->cred_guard_mutex);
1123} 1123}
1124EXPORT_SYMBOL(install_exec_creds); 1124EXPORT_SYMBOL(install_exec_creds);
1125 1125
1126/* 1126/*
1127 * determine how safe it is to execute the proposed program 1127 * determine how safe it is to execute the proposed program
1128 * - the caller must hold current->cred_guard_mutex to protect against 1128 * - the caller must hold ->cred_guard_mutex to protect against
1129 * PTRACE_ATTACH 1129 * PTRACE_ATTACH
1130 */ 1130 */
1131int check_unsafe_exec(struct linux_binprm *bprm) 1131int check_unsafe_exec(struct linux_binprm *bprm)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 9b094c1c8465..f3d02ca461ec 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -226,7 +226,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
226{ 226{
227 struct mm_struct *mm; 227 struct mm_struct *mm;
228 228
229 if (mutex_lock_killable(&task->cred_guard_mutex)) 229 if (mutex_lock_killable(&task->signal->cred_guard_mutex))
230 return NULL; 230 return NULL;
231 231
232 mm = get_task_mm(task); 232 mm = get_task_mm(task);
@@ -235,7 +235,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
235 mmput(mm); 235 mmput(mm);
236 mm = NULL; 236 mm = NULL;
237 } 237 }
238 mutex_unlock(&task->cred_guard_mutex); 238 mutex_unlock(&task->signal->cred_guard_mutex);
239 239
240 return mm; 240 return mm;
241} 241}
@@ -2354,14 +2354,14 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
2354 goto out_free; 2354 goto out_free;
2355 2355
2356 /* Guard against adverse ptrace interaction */ 2356 /* Guard against adverse ptrace interaction */
2357 length = mutex_lock_interruptible(&task->cred_guard_mutex); 2357 length = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
2358 if (length < 0) 2358 if (length < 0)
2359 goto out_free; 2359 goto out_free;
2360 2360
2361 length = security_setprocattr(task, 2361 length = security_setprocattr(task,
2362 (char*)file->f_path.dentry->d_name.name, 2362 (char*)file->f_path.dentry->d_name.name,
2363 (void*)page, count); 2363 (void*)page, count);
2364 mutex_unlock(&task->cred_guard_mutex); 2364 mutex_unlock(&task->signal->cred_guard_mutex);
2365out_free: 2365out_free:
2366 free_page((unsigned long) page); 2366 free_page((unsigned long) page);
2367out: 2367out:
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 2fea6c8ef6ba..1f8c06ce0fa6 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -29,6 +29,8 @@ extern struct fs_struct init_fs;
29 .running = 0, \ 29 .running = 0, \
30 .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \ 30 .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \
31 }, \ 31 }, \
32 .cred_guard_mutex = \
33 __MUTEX_INITIALIZER(sig.cred_guard_mutex), \
32} 34}
33 35
34extern struct nsproxy init_nsproxy; 36extern struct nsproxy init_nsproxy;
@@ -145,8 +147,6 @@ extern struct cred init_cred;
145 .group_leader = &tsk, \ 147 .group_leader = &tsk, \
146 RCU_INIT_POINTER(.real_cred, &init_cred), \ 148 RCU_INIT_POINTER(.real_cred, &init_cred), \
147 RCU_INIT_POINTER(.cred, &init_cred), \ 149 RCU_INIT_POINTER(.cred, &init_cred), \
148 .cred_guard_mutex = \
149 __MUTEX_INITIALIZER(tsk.cred_guard_mutex), \
150 .comm = "swapper", \ 150 .comm = "swapper", \
151 .thread = INIT_THREAD, \ 151 .thread = INIT_THREAD, \
152 .fs = &init_fs, \ 152 .fs = &init_fs, \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 3ff5c8519abd..be7adb7588e5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -626,6 +626,10 @@ struct signal_struct {
626 626
627 int oom_adj; /* OOM kill score adjustment (bit shift) */ 627 int oom_adj; /* OOM kill score adjustment (bit shift) */
628 int oom_score_adj; /* OOM kill score adjustment */ 628 int oom_score_adj; /* OOM kill score adjustment */
629
630 struct mutex cred_guard_mutex; /* guard against foreign influences on
631 * credential calculations
632 * (notably. ptrace) */
629}; 633};
630 634
631/* Context switch must be unlocked if interrupts are to be enabled */ 635/* Context switch must be unlocked if interrupts are to be enabled */
@@ -1305,9 +1309,6 @@ struct task_struct {
1305 * credentials (COW) */ 1309 * credentials (COW) */
1306 const struct cred __rcu *cred; /* effective (overridable) subjective task 1310 const struct cred __rcu *cred; /* effective (overridable) subjective task
1307 * credentials (COW) */ 1311 * credentials (COW) */
1308 struct mutex cred_guard_mutex; /* guard against foreign influences on
1309 * credential calculations
1310 * (notably. ptrace) */
1311 struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ 1312 struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
1312 1313
1313 char comm[TASK_COMM_LEN]; /* executable name excluding path 1314 char comm[TASK_COMM_LEN]; /* executable name excluding path
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 10db0102a890..3a2e66d88a32 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -150,7 +150,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
150 * 150 *
151 * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. 151 * Return %LSM_UNSAFE_* bits applied to an exec because of tracing.
152 * 152 *
153 * @task->cred_guard_mutex is held by the caller through the do_execve(). 153 * @task->signal->cred_guard_mutex is held by the caller through the do_execve().
154 */ 154 */
155static inline int tracehook_unsafe_exec(struct task_struct *task) 155static inline int tracehook_unsafe_exec(struct task_struct *task)
156{ 156{
diff --git a/kernel/cred.c b/kernel/cred.c
index 9a3e22641fe7..6a1aa004e376 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -325,7 +325,7 @@ EXPORT_SYMBOL(prepare_creds);
325 325
326/* 326/*
327 * Prepare credentials for current to perform an execve() 327 * Prepare credentials for current to perform an execve()
328 * - The caller must hold current->cred_guard_mutex 328 * - The caller must hold ->cred_guard_mutex
329 */ 329 */
330struct cred *prepare_exec_creds(void) 330struct cred *prepare_exec_creds(void)
331{ 331{
@@ -384,8 +384,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
384 struct cred *new; 384 struct cred *new;
385 int ret; 385 int ret;
386 386
387 mutex_init(&p->cred_guard_mutex);
388
389 if ( 387 if (
390#ifdef CONFIG_KEYS 388#ifdef CONFIG_KEYS
391 !p->cred->thread_keyring && 389 !p->cred->thread_keyring &&
diff --git a/kernel/fork.c b/kernel/fork.c
index e87aaaaf5131..3b159c5991b7 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -908,6 +908,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
908 sig->oom_adj = current->signal->oom_adj; 908 sig->oom_adj = current->signal->oom_adj;
909 sig->oom_score_adj = current->signal->oom_score_adj; 909 sig->oom_score_adj = current->signal->oom_score_adj;
910 910
911 mutex_init(&sig->cred_guard_mutex);
912
911 return 0; 913 return 0;
912} 914}
913 915
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index ea7ce0215cd1..99bbaa3e5b0d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -181,7 +181,7 @@ int ptrace_attach(struct task_struct *task)
181 * under ptrace. 181 * under ptrace.
182 */ 182 */
183 retval = -ERESTARTNOINTR; 183 retval = -ERESTARTNOINTR;
184 if (mutex_lock_interruptible(&task->cred_guard_mutex)) 184 if (mutex_lock_interruptible(&task->signal->cred_guard_mutex))
185 goto out; 185 goto out;
186 186
187 task_lock(task); 187 task_lock(task);
@@ -208,7 +208,7 @@ int ptrace_attach(struct task_struct *task)
208unlock_tasklist: 208unlock_tasklist:
209 write_unlock_irq(&tasklist_lock); 209 write_unlock_irq(&tasklist_lock);
210unlock_creds: 210unlock_creds:
211 mutex_unlock(&task->cred_guard_mutex); 211 mutex_unlock(&task->signal->cred_guard_mutex);
212out: 212out:
213 return retval; 213 return retval;
214} 214}