PTRACE_TRACEME CVE-2019-13272 本地提权漏洞解析
来源:岁月联盟
时间:2020-01-29
887 bool seized = child->ptrace & PT_SEIZED;
888 int ret = -EIO;
889 siginfo_t siginfo, *si;
890 void __user *datavp = (void __user *) data;
891 unsigned long __user *datalp = datavp;
892 unsigned long flags;
893
894 switch (request) {
895 case PTRACE_PEEKTEXT:
896 case PTRACE_PEEKDATA:
897 return generic_ptrace_peekdata(child, addr, data);
898 case PTRACE_POKETEXT:
899 case PTRACE_POKEDATA:
900 return generic_ptrace_pokedata(child, addr, data);
901
=================== skip ================
1105 }
1156 int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
1157 unsigned long data)
1158 {
1159 unsigned long tmp;
1160 int copied;
1161
1162 copied = ptrace_access_vm(tsk, addr, &tmp, sizeof(tmp), FOLL_FORCE); //
1163 if (copied != sizeof(tmp))
1164 return -EIO;
1165 return put_user(tmp, (unsigned long __user *)data);
1166 }
1167
1168 int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
1169 unsigned long data)
1170 {
1171 int copied;
1172
1173 copied = ptrace_access_vm(tsk, addr, &data, sizeof(data), //
1174 FOLL_FORCE | FOLL_WRITE);
1175 return (copied == sizeof(data)) ? 0 : -EIO;
1176 }
如上,当 tracer 想要控制 tracee 执行新的代码逻辑时,需要发送 request 读写 tracee 的代码区和内存区, 对应的 request 是 PTRACE_PEEKTEXT / PTRACE_PEEKDATA / PTRACE_POKETEXT / PTRACE_POKEDATA
这几种读写操作最终都是通过函数 ptrace_access_vm 实现的
kernel/ptrace.c
38 int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
39 void *buf, int len, unsigned int gup_flags)
40 {
41 struct mm_struct *mm;
42 int ret;
43
44 mm = get_task_mm(tsk);
45 if (!mm)
46 return 0;
47
48 if (!tsk->ptrace ||
49 (current != tsk->parent) ||
50 ((get_dumpable(mm) != SUID_DUMP_USER) &&
51 !ptracer_capable(tsk, mm->user_ns))) { //
52 mmput(mm);
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] 下一页