PR_SET_PTRACER参数疑问:ptracer应传入进程ID还是线程ID?
PR_SET_PTRACER需要传入进程ID还是线程ID? 从prctl文档的说明
PR_SET_PTRACER(Linux 3.4起支持)
仅当Yama LSM启用且处于模式1("受限ptrace",可通过/proc/sys/kernel/yama/ptrace_scope查看)时生效。当在arg2中传入一个"ptracer进程ID"时,调用进程声明该ptracer进程可以像直接祖先进程一样对调用进程执行ptrace(2)操作。每次PR_SET_PTRACER操作都会替换之前设置的"ptracer进程ID"。将arg2设为0调用PR_SET_PTRACER会清除调用进程的"ptracer进程ID"。如果arg2设为PR_SET_PTRACER_ANY,则Yama引入的ptrace限制对调用进程将不再生效。更多信息可查看内核源码文件
Documentation/admin-guide/LSM/Yama.rst(Linux 4.13之前为Documentation/security/Yama.txt)。
这段文档明确提到要传入的是ptracer进程ID,指向目标进程的PID。
从ptrace文档的说明
被追踪进程(tracee)首先需要附加到追踪进程(tracer)上。附加操作及后续命令都是按线程处理的:在多线程进程中,每个线程可以单独附加到某个(可能不同的)追踪进程,或者不附加从而不被调试。因此,"tracee"始终指"单个线程",而非"(可能多线程的)进程"。Ptrace命令总是通过如下形式的调用发送给特定的tracee:
ptrace(PTRACE_foo, pid, ...)其中
pid对应Linux线程的线程ID。
这里说明ptrace调用时的pid参数实际是线程ID,容易和PR_SET_PTRACER的描述产生混淆。
疑问解答:PR_SET_PTRACER的"ptracer process ID"到底是什么?
PR_SET_PTRACER的arg2需要传入的是进程ID(PID),而非线程ID,逻辑如下:
- Yama LSM的权限控制基于进程层面:授予某个进程PID对当前进程的ptrace权限后,该进程下的所有线程都可以对当前进程的任意线程执行ptrace操作(后续执行
ptrace时只需传入目标线程的TID即可)。 - 内核实现中,
PR_SET_PTRACER维护的是进程级别的信任列表,追踪的是进程PID而非单个线程的TID。设置完成后,整个ptracer进程都拥有对目标进程的ptrace权限,而非某个单独线程。 - 两者描述并不冲突:
PR_SET_PTRACER负责授予进程级别的ptrace权限,而ptrace调用参数负责指定具体操作的线程,是权限授予和实际执行的两个不同环节。
内容的提问来源于stack exchange,提问作者Jonathan Woollett-light

