diff options
-rw-r--r-- | fs/exec.c | 10 | ||||
-rw-r--r-- | fs/proc/base.c | 8 | ||||
-rw-r--r-- | include/linux/init_task.h | 4 | ||||
-rw-r--r-- | include/linux/sched.h | 7 | ||||
-rw-r--r-- | include/linux/tracehook.h | 2 | ||||
-rw-r--r-- | kernel/cred.c | 4 | ||||
-rw-r--r-- | kernel/fork.c | 2 | ||||
-rw-r--r-- | kernel/ptrace.c | 4 |
8 files changed, 21 insertions, 20 deletions
@@ -1083,14 +1083,14 @@ EXPORT_SYMBOL(setup_new_exec); | |||
1083 | */ | 1083 | */ |
1084 | int prepare_bprm_creds(struct linux_binprm *bprm) | 1084 | int prepare_bprm_creds(struct linux_binprm *bprm) |
1085 | { | 1085 | { |
1086 | if (mutex_lock_interruptible(¤t->cred_guard_mutex)) | 1086 | if (mutex_lock_interruptible(¤t->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(¤t->cred_guard_mutex); | 1093 | mutex_unlock(¤t->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(¤t->cred_guard_mutex); | 1101 | mutex_unlock(¤t->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(¤t->cred_guard_mutex); | 1122 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1123 | } | 1123 | } |
1124 | EXPORT_SYMBOL(install_exec_creds); | 1124 | EXPORT_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 | */ |
1131 | int check_unsafe_exec(struct linux_binprm *bprm) | 1131 | int 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); |
2365 | out_free: | 2365 | out_free: |
2366 | free_page((unsigned long) page); | 2366 | free_page((unsigned long) page); |
2367 | out: | 2367 | out: |
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 | ||
34 | extern struct nsproxy init_nsproxy; | 36 | extern 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 | */ |
155 | static inline int tracehook_unsafe_exec(struct task_struct *task) | 155 | static 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 | */ |
330 | struct cred *prepare_exec_creds(void) | 330 | struct 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) | |||
208 | unlock_tasklist: | 208 | unlock_tasklist: |
209 | write_unlock_irq(&tasklist_lock); | 209 | write_unlock_irq(&tasklist_lock); |
210 | unlock_creds: | 210 | unlock_creds: |
211 | mutex_unlock(&task->cred_guard_mutex); | 211 | mutex_unlock(&task->signal->cred_guard_mutex); |
212 | out: | 212 | out: |
213 | return retval; | 213 | return retval; |
214 | } | 214 | } |