接前一篇文章:Linux内核进程管理子系统有什么第三十七回 —— 进程主结构详解(33)
本文内容参考:
Linux内核进程管理专题报告_linux rseq-CSDN博客
《趣谈Linux操作系统 核心原理篇:第三部分 进程管理》—— 刘超
《图解Linux内核 基于6.x》 —— 姜亚华 机械工业出版社
特此致谢!
进程管理核心结构 —— task_struct
8. 进程权限相关成员
进程权限相关成员包括以下几个:
/* Process credentials: */
/* Tracer's credentials at attach: */
const struct cred __rcu *ptracer_cred;
/* Objective and real subjective task credentials (COW): */
const struct cred __rcu *real_cred;
/* Effective (overridable) subjective task credentials (COW): */
const struct cred __rcu *cred;
这几个字段的描述如下:
上一回讲了Subjective和Objective的概念,Subjective说白了就是“我能操作谁”,而Objective则是“谁能操作我”。
那么相对应地:
(1)struct cred *real_cred
real_cred字段是一个指针,指向主体和真实客体证书。
real_cred代表谁能操作本进程。实质上就是我这个进程操作别人时所具有的权限是什么。
(2)struct cred *cred
cred字段也是一个指针,指向有效客体证书。
cred代表本进程能操作谁。实质上就是别人操作我这个进程时需要具有的权限是什么。
(3)struct cred *ptracer_cred
要弄清楚这个字段的含义,需要先对ptrace进行知识补强。
知识补强 —— ptrace
如果想在用户空间程序中实现或模拟对进程的跟踪(trace)功能,特别是想要“attach”(附着)到一个特定的进程,可以使用多种方法。例如,使用ptrace(process trace)系统调用。
ptrace是一种机制,允许一个进程(称为tracer)监控另一个进程(称为trace)的执行。这在调试和系统监控方面非常有用。
使用ptrace机制的一般流程如下:
1)包含必要的头文件
首先需要包含<sys/ptrace.h>和<sys/types.h>等头文件。
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
2)使用ptrace附加到进程
可以使用ptrace函数配合PTRACE_ATTACH选项来附加到目标进程。
pid_t pid = 1234; // 目标进程的PID
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("ptrace");
exit(EXIT_FAILURE);
}
// 等待目标进程状态改变
waitpid(pid, NULL, 0);
3)执行跟踪操作
一旦附加成功,就可以读取或修改寄存器、内存等,或者简单地继续执行进程。
// 继续执行目标进程
if (ptrace(PTRACE_CONT, pid, NULL, NULL) == -1) {
perror("ptrace");
exit(EXIT_FAILURE);
}
4)分离进程
当完成跟踪后,应该使用PTRACE_DETACH选项来分离进程。
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
perror("ptrace");
exit(EXIT_FAILURE);
}
将以上步骤综合起来的完整ptrace示例代码如下:
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
pid_t pid = 1234; //目标进程的PID,需要根据实际情况修改
long w;
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
{
perror("ptrace");
exit(EXIT_FAILURE);
}
waitpid(pid, &w, 0); //等待子进程状态改变
printf("Attached to process %d\n", pid);
if (ptrace(PTRACE_CONT, pid, NULL, NULL) == -1)
{ //继续执行目标进程
perror("ptrace");
exit(EXIT_FAILURE);
}
waitpid(pid, &w, 0); //等待子进程状态改变以继续执行或停止等操作...
//更多操作...
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1)
{ //分离进程
perror("ptrace");
exit(EXIT_FAILURE);
}
printf("detached from process %d\n", pid);
return 0;
}
注意:
在使用ptrace时,需要有足够的权限(通常是root权限),因为大多数情况下,只有超级用户才能对其他用户的进程进行跟踪。
在实际使用中,确保处理好错误情况,例如目标进程不存在或没有足够的权限。
了解了ptrace机制后,struct cred *ptracer_cred这一字段的含义就好理解多了。其意义是:
在附着到某进程时,追踪者(tracer)需要具有的权限。
task_struct结构中进程权限相关成员的更多内容请看下回。