aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/kernel/ptrace.c2
-rw-r--r--arch/blackfin/kernel/ptrace.c4
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c2
-rw-r--r--arch/ia64/kernel/ptrace.c2
-rw-r--r--arch/mips/kernel/ptrace32.c4
-rw-r--r--arch/powerpc/kernel/ptrace32.c4
-rw-r--r--fs/exec.c21
-rw-r--r--include/linux/capability.h2
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/mm_types.h1
-rw-r--r--include/linux/ptrace.h4
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/capability.c36
-rw-r--r--kernel/fork.c9
-rw-r--r--kernel/ptrace.c70
-rw-r--r--mm/init-mm.c2
-rw-r--r--mm/memory.c2
-rw-r--r--mm/nommu.c2
-rw-r--r--security/integrity/evm/evm_crypto.c12
19 files changed, 139 insertions, 43 deletions
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 940dfb406591..04abdec7f496 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -283,7 +283,7 @@ long arch_ptrace(struct task_struct *child, long request,
283 /* When I and D space are separate, these will need to be fixed. */ 283 /* When I and D space are separate, these will need to be fixed. */
284 case PTRACE_PEEKTEXT: /* read word at location addr. */ 284 case PTRACE_PEEKTEXT: /* read word at location addr. */
285 case PTRACE_PEEKDATA: 285 case PTRACE_PEEKDATA:
286 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 286 copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp),
287 FOLL_FORCE); 287 FOLL_FORCE);
288 ret = -EIO; 288 ret = -EIO;
289 if (copied != sizeof(tmp)) 289 if (copied != sizeof(tmp))
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 8d79286ee4e8..360d99645163 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -270,7 +270,7 @@ long arch_ptrace(struct task_struct *child, long request,
270 switch (bfin_mem_access_type(addr, to_copy)) { 270 switch (bfin_mem_access_type(addr, to_copy)) {
271 case BFIN_MEM_ACCESS_CORE: 271 case BFIN_MEM_ACCESS_CORE:
272 case BFIN_MEM_ACCESS_CORE_ONLY: 272 case BFIN_MEM_ACCESS_CORE_ONLY:
273 copied = access_process_vm(child, addr, &tmp, 273 copied = ptrace_access_vm(child, addr, &tmp,
274 to_copy, FOLL_FORCE); 274 to_copy, FOLL_FORCE);
275 if (copied) 275 if (copied)
276 break; 276 break;
@@ -323,7 +323,7 @@ long arch_ptrace(struct task_struct *child, long request,
323 switch (bfin_mem_access_type(addr, to_copy)) { 323 switch (bfin_mem_access_type(addr, to_copy)) {
324 case BFIN_MEM_ACCESS_CORE: 324 case BFIN_MEM_ACCESS_CORE:
325 case BFIN_MEM_ACCESS_CORE_ONLY: 325 case BFIN_MEM_ACCESS_CORE_ONLY:
326 copied = access_process_vm(child, addr, &data, 326 copied = ptrace_access_vm(child, addr, &data,
327 to_copy, 327 to_copy,
328 FOLL_FORCE | FOLL_WRITE); 328 FOLL_FORCE | FOLL_WRITE);
329 break; 329 break;
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index f0df654ac6fc..fe1f9cf7b391 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -147,7 +147,7 @@ long arch_ptrace(struct task_struct *child, long request,
147 /* The trampoline page is globally mapped, no page table to traverse.*/ 147 /* The trampoline page is globally mapped, no page table to traverse.*/
148 tmp = *(unsigned long*)addr; 148 tmp = *(unsigned long*)addr;
149 } else { 149 } else {
150 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), FOLL_FORCE); 150 copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp), FOLL_FORCE);
151 151
152 if (copied != sizeof(tmp)) 152 if (copied != sizeof(tmp))
153 break; 153 break;
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 31aa8c0f68e1..36f660da8124 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1159,7 +1159,7 @@ arch_ptrace (struct task_struct *child, long request,
1159 case PTRACE_PEEKTEXT: 1159 case PTRACE_PEEKTEXT:
1160 case PTRACE_PEEKDATA: 1160 case PTRACE_PEEKDATA:
1161 /* read word at location addr */ 1161 /* read word at location addr */
1162 if (access_process_vm(child, addr, &data, sizeof(data), 1162 if (ptrace_access_vm(child, addr, &data, sizeof(data),
1163 FOLL_FORCE) 1163 FOLL_FORCE)
1164 != sizeof(data)) 1164 != sizeof(data))
1165 return -EIO; 1165 return -EIO;
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 7e71a4e0281b..5fcbdcd7abd0 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -69,7 +69,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
69 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0) 69 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
70 break; 70 break;
71 71
72 copied = access_process_vm(child, (u64)addrOthers, &tmp, 72 copied = ptrace_access_vm(child, (u64)addrOthers, &tmp,
73 sizeof(tmp), FOLL_FORCE); 73 sizeof(tmp), FOLL_FORCE);
74 if (copied != sizeof(tmp)) 74 if (copied != sizeof(tmp))
75 break; 75 break;
@@ -178,7 +178,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
178 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0) 178 if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
179 break; 179 break;
180 ret = 0; 180 ret = 0;
181 if (access_process_vm(child, (u64)addrOthers, &data, 181 if (ptrace_access_vm(child, (u64)addrOthers, &data,
182 sizeof(data), 182 sizeof(data),
183 FOLL_FORCE | FOLL_WRITE) == sizeof(data)) 183 FOLL_FORCE | FOLL_WRITE) == sizeof(data))
184 break; 184 break;
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 010b7b310237..1e887f3a61a6 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -73,7 +73,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
73 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0) 73 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
74 break; 74 break;
75 75
76 copied = access_process_vm(child, (u64)addrOthers, &tmp, 76 copied = ptrace_access_vm(child, (u64)addrOthers, &tmp,
77 sizeof(tmp), FOLL_FORCE); 77 sizeof(tmp), FOLL_FORCE);
78 if (copied != sizeof(tmp)) 78 if (copied != sizeof(tmp))
79 break; 79 break;
@@ -178,7 +178,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
178 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0) 178 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
179 break; 179 break;
180 ret = 0; 180 ret = 0;
181 if (access_process_vm(child, (u64)addrOthers, &tmp, 181 if (ptrace_access_vm(child, (u64)addrOthers, &tmp,
182 sizeof(tmp), 182 sizeof(tmp),
183 FOLL_FORCE | FOLL_WRITE) == sizeof(tmp)) 183 FOLL_FORCE | FOLL_WRITE) == sizeof(tmp))
184 break; 184 break;
diff --git a/fs/exec.c b/fs/exec.c
index 923c57d96899..88b5e1efdbd6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1277,8 +1277,22 @@ EXPORT_SYMBOL(flush_old_exec);
1277 1277
1278void would_dump(struct linux_binprm *bprm, struct file *file) 1278void would_dump(struct linux_binprm *bprm, struct file *file)
1279{ 1279{
1280 if (inode_permission(file_inode(file), MAY_READ) < 0) 1280 struct inode *inode = file_inode(file);
1281 if (inode_permission(inode, MAY_READ) < 0) {
1282 struct user_namespace *old, *user_ns;
1281 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; 1283 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1284
1285 /* Ensure mm->user_ns contains the executable */
1286 user_ns = old = bprm->mm->user_ns;
1287 while ((user_ns != &init_user_ns) &&
1288 !privileged_wrt_inode_uidgid(user_ns, inode))
1289 user_ns = user_ns->parent;
1290
1291 if (old != user_ns) {
1292 bprm->mm->user_ns = get_user_ns(user_ns);
1293 put_user_ns(old);
1294 }
1295 }
1282} 1296}
1283EXPORT_SYMBOL(would_dump); 1297EXPORT_SYMBOL(would_dump);
1284 1298
@@ -1308,7 +1322,6 @@ void setup_new_exec(struct linux_binprm * bprm)
1308 !gid_eq(bprm->cred->gid, current_egid())) { 1322 !gid_eq(bprm->cred->gid, current_egid())) {
1309 current->pdeath_signal = 0; 1323 current->pdeath_signal = 0;
1310 } else { 1324 } else {
1311 would_dump(bprm, bprm->file);
1312 if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) 1325 if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
1313 set_dumpable(current->mm, suid_dumpable); 1326 set_dumpable(current->mm, suid_dumpable);
1314 } 1327 }
@@ -1408,7 +1421,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
1408 unsigned n_fs; 1421 unsigned n_fs;
1409 1422
1410 if (p->ptrace) { 1423 if (p->ptrace) {
1411 if (p->ptrace & PT_PTRACE_CAP) 1424 if (ptracer_capable(p, current_user_ns()))
1412 bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP; 1425 bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
1413 else 1426 else
1414 bprm->unsafe |= LSM_UNSAFE_PTRACE; 1427 bprm->unsafe |= LSM_UNSAFE_PTRACE;
@@ -1743,6 +1756,8 @@ static int do_execveat_common(int fd, struct filename *filename,
1743 if (retval < 0) 1756 if (retval < 0)
1744 goto out; 1757 goto out;
1745 1758
1759 would_dump(bprm, bprm->file);
1760
1746 retval = exec_binprm(bprm); 1761 retval = exec_binprm(bprm);
1747 if (retval < 0) 1762 if (retval < 0)
1748 goto out; 1763 goto out;
diff --git a/include/linux/capability.h b/include/linux/capability.h
index dbc21c719ce6..6ffb67e10c06 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -240,8 +240,10 @@ static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
240 return true; 240 return true;
241} 241}
242#endif /* CONFIG_MULTIUSER */ 242#endif /* CONFIG_MULTIUSER */
243extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
243extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap); 244extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
244extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); 245extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
246extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
245 247
246/* audit system wants to get cap info from files as well */ 248/* audit system wants to get cap info from files as well */
247extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); 249extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a92c8d73aeaf..0b5b2e4df14e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1270,6 +1270,8 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *
1270 unsigned int gup_flags); 1270 unsigned int gup_flags);
1271extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, 1271extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
1272 void *buf, int len, unsigned int gup_flags); 1272 void *buf, int len, unsigned int gup_flags);
1273extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
1274 unsigned long addr, void *buf, int len, unsigned int gup_flags);
1273 1275
1274long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, 1276long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
1275 unsigned long start, unsigned long nr_pages, 1277 unsigned long start, unsigned long nr_pages,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 4a8acedf4b7d..08d947fc4c59 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -473,6 +473,7 @@ struct mm_struct {
473 */ 473 */
474 struct task_struct __rcu *owner; 474 struct task_struct __rcu *owner;
475#endif 475#endif
476 struct user_namespace *user_ns;
476 477
477 /* store ref to file /proc/<pid>/exe symlink points to */ 478 /* store ref to file /proc/<pid>/exe symlink points to */
478 struct file __rcu *exe_file; 479 struct file __rcu *exe_file;
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 504c98a278d4..e0e539321ab9 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -8,6 +8,9 @@
8#include <linux/pid_namespace.h> /* For task_active_pid_ns. */ 8#include <linux/pid_namespace.h> /* For task_active_pid_ns. */
9#include <uapi/linux/ptrace.h> 9#include <uapi/linux/ptrace.h>
10 10
11extern int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
12 void *buf, int len, unsigned int gup_flags);
13
11/* 14/*
12 * Ptrace flags 15 * Ptrace flags
13 * 16 *
@@ -19,7 +22,6 @@
19#define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */ 22#define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */
20#define PT_PTRACED 0x00000001 23#define PT_PTRACED 0x00000001
21#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ 24#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */
22#define PT_PTRACE_CAP 0x00000004 /* ptracer can follow suid-exec */
23 25
24#define PT_OPT_FLAG_SHIFT 3 26#define PT_OPT_FLAG_SHIFT 3
25/* PT_TRACE_* event enable flags */ 27/* PT_TRACE_* event enable flags */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5ccbbfe41345..a440cf178191 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1685,6 +1685,7 @@ struct task_struct {
1685 struct list_head cpu_timers[3]; 1685 struct list_head cpu_timers[3];
1686 1686
1687/* process credentials */ 1687/* process credentials */
1688 const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
1688 const struct cred __rcu *real_cred; /* objective and real subjective task 1689 const struct cred __rcu *real_cred; /* objective and real subjective task
1689 * credentials (COW) */ 1690 * credentials (COW) */
1690 const struct cred __rcu *cred; /* effective (overridable) subjective task 1691 const struct cred __rcu *cred; /* effective (overridable) subjective task
diff --git a/kernel/capability.c b/kernel/capability.c
index 00411c82dac5..4984e1f552eb 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -457,6 +457,19 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
457EXPORT_SYMBOL(file_ns_capable); 457EXPORT_SYMBOL(file_ns_capable);
458 458
459/** 459/**
460 * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
461 * @ns: The user namespace in question
462 * @inode: The inode in question
463 *
464 * Return true if the inode uid and gid are within the namespace.
465 */
466bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
467{
468 return kuid_has_mapping(ns, inode->i_uid) &&
469 kgid_has_mapping(ns, inode->i_gid);
470}
471
472/**
460 * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped 473 * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
461 * @inode: The inode in question 474 * @inode: The inode in question
462 * @cap: The capability in question 475 * @cap: The capability in question
@@ -469,7 +482,26 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
469{ 482{
470 struct user_namespace *ns = current_user_ns(); 483 struct user_namespace *ns = current_user_ns();
471 484
472 return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) && 485 return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
473 kgid_has_mapping(ns, inode->i_gid);
474} 486}
475EXPORT_SYMBOL(capable_wrt_inode_uidgid); 487EXPORT_SYMBOL(capable_wrt_inode_uidgid);
488
489/**
490 * ptracer_capable - Determine if the ptracer holds CAP_SYS_PTRACE in the namespace
491 * @tsk: The task that may be ptraced
492 * @ns: The user namespace to search for CAP_SYS_PTRACE in
493 *
494 * Return true if the task that is ptracing the current task had CAP_SYS_PTRACE
495 * in the specified user namespace.
496 */
497bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns)
498{
499 int ret = 0; /* An absent tracer adds no restrictions */
500 const struct cred *cred;
501 rcu_read_lock();
502 cred = rcu_dereference(tsk->ptracer_cred);
503 if (cred)
504 ret = security_capable_noaudit(cred, ns, CAP_SYS_PTRACE);
505 rcu_read_unlock();
506 return (ret == 0);
507}
diff --git a/kernel/fork.c b/kernel/fork.c
index a439ac429669..869b8ccc00bf 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -747,7 +747,8 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
747#endif 747#endif
748} 748}
749 749
750static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) 750static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
751 struct user_namespace *user_ns)
751{ 752{
752 mm->mmap = NULL; 753 mm->mmap = NULL;
753 mm->mm_rb = RB_ROOT; 754 mm->mm_rb = RB_ROOT;
@@ -787,6 +788,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
787 if (init_new_context(p, mm)) 788 if (init_new_context(p, mm))
788 goto fail_nocontext; 789 goto fail_nocontext;
789 790
791 mm->user_ns = get_user_ns(user_ns);
790 return mm; 792 return mm;
791 793
792fail_nocontext: 794fail_nocontext:
@@ -832,7 +834,7 @@ struct mm_struct *mm_alloc(void)
832 return NULL; 834 return NULL;
833 835
834 memset(mm, 0, sizeof(*mm)); 836 memset(mm, 0, sizeof(*mm));
835 return mm_init(mm, current); 837 return mm_init(mm, current, current_user_ns());
836} 838}
837 839
838/* 840/*
@@ -847,6 +849,7 @@ void __mmdrop(struct mm_struct *mm)
847 destroy_context(mm); 849 destroy_context(mm);
848 mmu_notifier_mm_destroy(mm); 850 mmu_notifier_mm_destroy(mm);
849 check_mm(mm); 851 check_mm(mm);
852 put_user_ns(mm->user_ns);
850 free_mm(mm); 853 free_mm(mm);
851} 854}
852EXPORT_SYMBOL_GPL(__mmdrop); 855EXPORT_SYMBOL_GPL(__mmdrop);
@@ -1128,7 +1131,7 @@ static struct mm_struct *dup_mm(struct task_struct *tsk)
1128 1131
1129 memcpy(mm, oldmm, sizeof(*mm)); 1132 memcpy(mm, oldmm, sizeof(*mm));
1130 1133
1131 if (!mm_init(mm, tsk)) 1134 if (!mm_init(mm, tsk, mm->user_ns))
1132 goto fail_nomem; 1135 goto fail_nomem;
1133 1136
1134 err = dup_mmap(mm, oldmm); 1137 err = dup_mmap(mm, oldmm);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index e6474f7272ec..49ba7c1ade9d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -27,6 +27,35 @@
27#include <linux/cn_proc.h> 27#include <linux/cn_proc.h>
28#include <linux/compat.h> 28#include <linux/compat.h>
29 29
30/*
31 * Access another process' address space via ptrace.
32 * Source/target buffer must be kernel space,
33 * Do not walk the page table directly, use get_user_pages
34 */
35int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
36 void *buf, int len, unsigned int gup_flags)
37{
38 struct mm_struct *mm;
39 int ret;
40
41 mm = get_task_mm(tsk);
42 if (!mm)
43 return 0;
44
45 if (!tsk->ptrace ||
46 (current != tsk->parent) ||
47 ((get_dumpable(mm) != SUID_DUMP_USER) &&
48 !ptracer_capable(tsk, mm->user_ns))) {
49 mmput(mm);
50 return 0;
51 }
52
53 ret = __access_remote_vm(tsk, mm, addr, buf, len, gup_flags);
54 mmput(mm);
55
56 return ret;
57}
58
30 59
31/* 60/*
32 * ptrace a task: make the debugger its new parent and 61 * ptrace a task: make the debugger its new parent and
@@ -39,6 +68,9 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
39 BUG_ON(!list_empty(&child->ptrace_entry)); 68 BUG_ON(!list_empty(&child->ptrace_entry));
40 list_add(&child->ptrace_entry, &new_parent->ptraced); 69 list_add(&child->ptrace_entry, &new_parent->ptraced);
41 child->parent = new_parent; 70 child->parent = new_parent;
71 rcu_read_lock();
72 child->ptracer_cred = get_cred(__task_cred(new_parent));
73 rcu_read_unlock();
42} 74}
43 75
44/** 76/**
@@ -71,12 +103,16 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
71 */ 103 */
72void __ptrace_unlink(struct task_struct *child) 104void __ptrace_unlink(struct task_struct *child)
73{ 105{
106 const struct cred *old_cred;
74 BUG_ON(!child->ptrace); 107 BUG_ON(!child->ptrace);
75 108
76 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 109 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
77 110
78 child->parent = child->real_parent; 111 child->parent = child->real_parent;
79 list_del_init(&child->ptrace_entry); 112 list_del_init(&child->ptrace_entry);
113 old_cred = child->ptracer_cred;
114 child->ptracer_cred = NULL;
115 put_cred(old_cred);
80 116
81 spin_lock(&child->sighand->siglock); 117 spin_lock(&child->sighand->siglock);
82 child->ptrace = 0; 118 child->ptrace = 0;
@@ -220,7 +256,7 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
220static int __ptrace_may_access(struct task_struct *task, unsigned int mode) 256static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
221{ 257{
222 const struct cred *cred = current_cred(), *tcred; 258 const struct cred *cred = current_cred(), *tcred;
223 int dumpable = 0; 259 struct mm_struct *mm;
224 kuid_t caller_uid; 260 kuid_t caller_uid;
225 kgid_t caller_gid; 261 kgid_t caller_gid;
226 262
@@ -271,16 +307,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
271 return -EPERM; 307 return -EPERM;
272ok: 308ok:
273 rcu_read_unlock(); 309 rcu_read_unlock();
274 smp_rmb(); 310 mm = task->mm;
275 if (task->mm) 311 if (mm &&
276 dumpable = get_dumpable(task->mm); 312 ((get_dumpable(mm) != SUID_DUMP_USER) &&
277 rcu_read_lock(); 313 !ptrace_has_cap(mm->user_ns, mode)))
278 if (dumpable != SUID_DUMP_USER && 314 return -EPERM;
279 !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
280 rcu_read_unlock();
281 return -EPERM;
282 }
283 rcu_read_unlock();
284 315
285 return security_ptrace_access_check(task, mode); 316 return security_ptrace_access_check(task, mode);
286} 317}
@@ -344,10 +375,6 @@ static int ptrace_attach(struct task_struct *task, long request,
344 375
345 if (seize) 376 if (seize)
346 flags |= PT_SEIZED; 377 flags |= PT_SEIZED;
347 rcu_read_lock();
348 if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE))
349 flags |= PT_PTRACE_CAP;
350 rcu_read_unlock();
351 task->ptrace = flags; 378 task->ptrace = flags;
352 379
353 __ptrace_link(task, current); 380 __ptrace_link(task, current);
@@ -537,7 +564,8 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst
537 int this_len, retval; 564 int this_len, retval;
538 565
539 this_len = (len > sizeof(buf)) ? sizeof(buf) : len; 566 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
540 retval = access_process_vm(tsk, src, buf, this_len, FOLL_FORCE); 567 retval = ptrace_access_vm(tsk, src, buf, this_len, FOLL_FORCE);
568
541 if (!retval) { 569 if (!retval) {
542 if (copied) 570 if (copied)
543 break; 571 break;
@@ -564,7 +592,7 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
564 this_len = (len > sizeof(buf)) ? sizeof(buf) : len; 592 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
565 if (copy_from_user(buf, src, this_len)) 593 if (copy_from_user(buf, src, this_len))
566 return -EFAULT; 594 return -EFAULT;
567 retval = access_process_vm(tsk, dst, buf, this_len, 595 retval = ptrace_access_vm(tsk, dst, buf, this_len,
568 FOLL_FORCE | FOLL_WRITE); 596 FOLL_FORCE | FOLL_WRITE);
569 if (!retval) { 597 if (!retval) {
570 if (copied) 598 if (copied)
@@ -1128,7 +1156,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
1128 unsigned long tmp; 1156 unsigned long tmp;
1129 int copied; 1157 int copied;
1130 1158
1131 copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), FOLL_FORCE); 1159 copied = ptrace_access_vm(tsk, addr, &tmp, sizeof(tmp), FOLL_FORCE);
1132 if (copied != sizeof(tmp)) 1160 if (copied != sizeof(tmp))
1133 return -EIO; 1161 return -EIO;
1134 return put_user(tmp, (unsigned long __user *)data); 1162 return put_user(tmp, (unsigned long __user *)data);
@@ -1139,7 +1167,7 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
1139{ 1167{
1140 int copied; 1168 int copied;
1141 1169
1142 copied = access_process_vm(tsk, addr, &data, sizeof(data), 1170 copied = ptrace_access_vm(tsk, addr, &data, sizeof(data),
1143 FOLL_FORCE | FOLL_WRITE); 1171 FOLL_FORCE | FOLL_WRITE);
1144 return (copied == sizeof(data)) ? 0 : -EIO; 1172 return (copied == sizeof(data)) ? 0 : -EIO;
1145} 1173}
@@ -1157,7 +1185,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
1157 switch (request) { 1185 switch (request) {
1158 case PTRACE_PEEKTEXT: 1186 case PTRACE_PEEKTEXT:
1159 case PTRACE_PEEKDATA: 1187 case PTRACE_PEEKDATA:
1160 ret = access_process_vm(child, addr, &word, sizeof(word), 1188 ret = ptrace_access_vm(child, addr, &word, sizeof(word),
1161 FOLL_FORCE); 1189 FOLL_FORCE);
1162 if (ret != sizeof(word)) 1190 if (ret != sizeof(word))
1163 ret = -EIO; 1191 ret = -EIO;
@@ -1167,7 +1195,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
1167 1195
1168 case PTRACE_POKETEXT: 1196 case PTRACE_POKETEXT:
1169 case PTRACE_POKEDATA: 1197 case PTRACE_POKEDATA:
1170 ret = access_process_vm(child, addr, &data, sizeof(data), 1198 ret = ptrace_access_vm(child, addr, &data, sizeof(data),
1171 FOLL_FORCE | FOLL_WRITE); 1199 FOLL_FORCE | FOLL_WRITE);
1172 ret = (ret != sizeof(data) ? -EIO : 0); 1200 ret = (ret != sizeof(data) ? -EIO : 0);
1173 break; 1201 break;
diff --git a/mm/init-mm.c b/mm/init-mm.c
index a56a851908d2..975e49f00f34 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -6,6 +6,7 @@
6#include <linux/cpumask.h> 6#include <linux/cpumask.h>
7 7
8#include <linux/atomic.h> 8#include <linux/atomic.h>
9#include <linux/user_namespace.h>
9#include <asm/pgtable.h> 10#include <asm/pgtable.h>
10#include <asm/mmu.h> 11#include <asm/mmu.h>
11 12
@@ -21,5 +22,6 @@ struct mm_struct init_mm = {
21 .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), 22 .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem),
22 .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), 23 .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
23 .mmlist = LIST_HEAD_INIT(init_mm.mmlist), 24 .mmlist = LIST_HEAD_INIT(init_mm.mmlist),
25 .user_ns = &init_user_ns,
24 INIT_MM_CONTEXT(init_mm) 26 INIT_MM_CONTEXT(init_mm)
25}; 27};
diff --git a/mm/memory.c b/mm/memory.c
index c264f7cd3e47..08d8da39de28 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3904,7 +3904,7 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
3904 * Access another process' address space as given in mm. If non-NULL, use the 3904 * Access another process' address space as given in mm. If non-NULL, use the
3905 * given task for page fault accounting. 3905 * given task for page fault accounting.
3906 */ 3906 */
3907static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, 3907int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
3908 unsigned long addr, void *buf, int len, unsigned int gup_flags) 3908 unsigned long addr, void *buf, int len, unsigned int gup_flags)
3909{ 3909{
3910 struct vm_area_struct *vma; 3910 struct vm_area_struct *vma;
diff --git a/mm/nommu.c b/mm/nommu.c
index 9720e0bab029..27bc543128e5 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1808,7 +1808,7 @@ void filemap_map_pages(struct fault_env *fe,
1808} 1808}
1809EXPORT_SYMBOL(filemap_map_pages); 1809EXPORT_SYMBOL(filemap_map_pages);
1810 1810
1811static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, 1811int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
1812 unsigned long addr, void *buf, int len, unsigned int gup_flags) 1812 unsigned long addr, void *buf, int len, unsigned int gup_flags)
1813{ 1813{
1814 struct vm_area_struct *vma; 1814 struct vm_area_struct *vma;
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index bf663915412e..d7f282d75cc1 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -151,8 +151,16 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
151 memset(&hmac_misc, 0, sizeof(hmac_misc)); 151 memset(&hmac_misc, 0, sizeof(hmac_misc));
152 hmac_misc.ino = inode->i_ino; 152 hmac_misc.ino = inode->i_ino;
153 hmac_misc.generation = inode->i_generation; 153 hmac_misc.generation = inode->i_generation;
154 hmac_misc.uid = from_kuid(inode->i_sb->s_user_ns, inode->i_uid); 154 /* The hmac uid and gid must be encoded in the initial user
155 hmac_misc.gid = from_kgid(inode->i_sb->s_user_ns, inode->i_gid); 155 * namespace (not the filesystems user namespace) as encoding
156 * them in the filesystems user namespace allows an attack
157 * where first they are written in an unprivileged fuse mount
158 * of a filesystem and then the system is tricked to mount the
159 * filesystem for real on next boot and trust it because
160 * everything is signed.
161 */
162 hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
163 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
156 hmac_misc.mode = inode->i_mode; 164 hmac_misc.mode = inode->i_mode;
157 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); 165 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
158 if (evm_hmac_attrs & EVM_ATTR_FSUUID) 166 if (evm_hmac_attrs & EVM_ATTR_FSUUID)