Linux内核进程管理子系统有什么第三十八回 —— 进程主结构详解(34)

发布于:2025-08-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

接前一篇文章: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结构中进程权限相关成员的更多内容请看下回。