Bootstrap

linux prctl函数使用说明

prctl 是 Linux 系统调用,用于对进程的某些特性进行控制和操作。它的主要作用是设置或获取进程的某些特定属性,例如进程名、允许的系统调用行为等。

下面是 prctl 函数的常见用法及其参数说明:

#include <sys/prctl.h>
#include <linux/prctl.h>

常用选项

  1. PR_SET_NAMEPR_GET_NAME: 设置或获取进程名。
  2. PR_SET_PDEATHSIG: 当父进程退出时,发送信号给子进程。
  3. PR_GET_SECCOMPPR_SET_SECCOMP: 获取或设置进程的 seccomp 模式(用于限制系统调用)。
  4. PR_SET_NO_NEW_PRIVS: 禁止提升权限(例如使用 setuid 程序)。

示例代码

1. 设置和获取进程名
#include <stdio.h>
#include <string.h>
#include <sys/prctl.h>

int main() {
    char name[16]; // 进程名最大长度为 16 字节(包括终止符)
    
    // 设置进程名
    if (prctl(PR_SET_NAME, "MyProcess", 0, 0, 0) != 0) {
        perror("prctl PR_SET_NAME failed");
        return 1;
    }
    
    // 获取进程名
    if (prctl(PR_GET_NAME, name, 0, 0, 0) != 0) {
        perror("prctl PR_GET_NAME failed");
        return 1;
    }

    printf("Process name: %s\n", name);
    return 0;
}

运行后,使用 ps 命令可以看到进程名已设置为 MyProcess


2. 父进程退出时通知子进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h>

void handle_signal(int sig) {
    printf("Received signal: %d\n", sig);
    exit(0);
}

int main() {
    // 子进程设置:父进程退出时发送 SIGKILL
    if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0) {
        perror("prctl PR_SET_PDEATHSIG failed");
        return 1;
    }

    // 父进程退出时,子进程会收到 SIGKILL 信号
    signal(SIGKILL, handle_signal);

    printf("Running child process (pid: %d, ppid: %d)\n", getpid(), getppid());

    // 模拟长时间运行
    while (1) {
        sleep(1);
    }
    return 0;
}

运行此代码时,若父进程退出(通过 killCtrl+C),子进程会自动接收到 SIGKILL 信号并终止。


3. 设置 Seccomp 模式

以下示例设置 seccomp 为只允许 readwrite 系统调用(限制进程行为):

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <linux/audit.h>

int main() {
    // 开启 seccomp 过滤器(仅允许 read 和 write)
    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT) == -1) {
        perror("prctl PR_SET_SECCOMP failed");
        return 1;
    }

    printf("Seccomp mode enabled.\n");

    // 以下操作将被允许
    write(STDOUT_FILENO, "Hello, Seccomp!\n", 16);

    // 以下操作会导致进程终止(不允许的系统调用)
    if (fork() == -1) {
        perror("fork failed");
    }

    return 0;
}

prctl 设置为 SECCOMP_MODE_STRICT 时,只允许 readwrite 系统调用,其他调用(例如 fork)会被直接阻止并终止程序。


总结

prctl 提供了强大的进程属性管理能力。它常被用于:

  • 设置进程名,方便调试和监控;
  • 配置 seccomp 来限制进程系统调用,提升安全性;
  • 配置父子进程通信行为。

通过结合 prctl 的功能,开发者可以更加精细地控制进程行为。

;