capset系统调用及示例
34. capget - 获取进程能力
函数介绍
capget
系统调用用于获取进程的能力状态信息。能力是一种细粒度的权限控制机制,将传统的超级用户权限分解为独立的权限单元。
函数原型
#include <linux/capability.h>
#include <sys/syscall.h>
#include <unistd.h>int capget(cap_user_header_t hdrp, cap_user_data_t datap);
功能
获取指定进程的能力集,包括有效能力、允许能力和可继承能力。
参数
cap_user_header_t hdrp
: 指向头部结构的指针,包含版本和进程IDcap_user_data_t datap
: 指向能力数据结构的指针
返回值
- 成功时返回0
- 失败时返回-1,并设置errno
相似函数
capset()
: 设置进程能力prctl()
: 进程控制函数
示例代码
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/capability.h>
#include <errno.h>
#include <string.h>// 系统调用包装
static int capget_wrapper(cap_user_header_t hdrp, cap_user_data_t datap) {return syscall(__NR_capget, hdrp, datap);
}// 打印能力位图
void print_capabilities(const char *label, __u32 caps) {printf("%s: 0x%08x (", label, caps);if (caps == 0) {printf("none");} else {int first = 1;for (int i = 0; i < 32; i++) {if (caps & (1 << i)) {if (!first) printf(" ");first = 0;switch (i) {case 0: printf("CAP_CHOWN"); break;case 1: printf("CAP_DAC_OVERRIDE"); break;case 2: printf("CAP_DAC_READ_SEARCH"); break;case 3: printf("CAP_FOWNER"); break;case 4: printf("CAP_FSETID"); break;case 5: printf("CAP_KILL"); break;case 6: printf("CAP_SETGID"); break;case 7: printf("CAP_SETUID"); break;case 8: printf("CAP_SETPCAP"); break;case 9: printf("CAP_LINUX_IMMUTABLE"); break;case 10: printf("CAP_NET_BIND_SERVICE"); break;case 11: printf("CAP_NET_BROADCAST"); break;case 12: printf("CAP_NET_ADMIN"); break;case 13: printf("CAP_SYS_MODULE"); break;case 14: printf("CAP_SYS_RAWIO"); break;case 15: printf("CAP_SYS_CHROOT"); break;case 16: printf("CAP_SYS_PTRACE"); break;case 17: printf("CAP_SYS_PACCT"); break;case 18: printf("CAP_SYS_ADMIN"); break;case 19: printf("CAP_SYS_BOOT"); break;case 20: printf("CAP_SYS_NICE"); break;case 21: printf("CAP_SYS_RESOURCE"); break;case 22: printf("CAP_SYS_TIME"); break;case 23: printf("CAP_SYS_TTY_CONFIG"); break;case 24: printf("CAP_MKNOD"); break;case 25: printf("CAP_LEASE"); break;case 26: printf("CAP_AUDIT_WRITE"); break;case 27: printf("CAP_AUDIT_CONTROL"); break;case 28: printf("CAP_SETFCAP"); break;case 29: printf("CAP_MAC_OVERRIDE"); break;case 30: printf("CAP_MAC_ADMIN"); break;case 31: printf("CAP_SYSLOG"); break;default: printf("CAP_%d", i); break;}}}}printf(")\n");
}int main() {struct __user_cap_header_struct hdr;struct __user_cap_data_struct data[2];printf("=== Capget 函数示例 ===\n");printf("当前进程 PID: %d\n", getpid());printf("当前用户 UID: %d\n", getuid());printf("当前有效 UID: %d\n", geteuid());// 设置头部信息hdr.version = _LINUX_CAPABILITY_VERSION_3;hdr.pid = 0; // 当前进程// 获取能力信息if (capget_wrapper(&hdr, data) == -1) {perror("capget 失败");exit(EXIT_FAILURE);}printf("\n进程能力信息:\n");printf("能力版本: 0x%08x\n", hdr.version);printf("进程 PID: %d\n", hdr.pid);// 显示能力集printf("\n能力集详情:\n");print_capabilities("有效能力 (Effective)", data[0].effective);print_capabilities("允许能力 (Permitted)", data[0].permitted);print_capabilities("可继承能力 (Inheritable)", data[0].inheritable);// 分析当前能力状态printf("\n能力状态分析:\n");if (geteuid() == 0) {printf("✓ 当前进程是 root 用户\n");if (data[0].effective == 0 && data[0].permitted == 0) {printf(" 但所有能力都被丢弃\n");} else {printf(" 拥有完整的 root 能力\n");}} else {printf("✓ 当前进程是非特权用户\n");if (data[0].effective == 0) {printf(" 没有有效能力\n");} else {printf(" 拥有一些特定能力\n");}}// 错误处理演示printf("\n错误处理演示:\n");// 无效版本号struct __user_cap_header_struct bad_hdr;bad_hdr.version = 0x12345678;bad_hdr.pid = 0;if (capget_wrapper(&bad_hdr, data) == -1) {if (errno == EINVAL) {printf("无效版本号错误处理正确: %s\n", strerror(errno));}}// 无效指针hdr.version = _LINUX_CAPABILITY_VERSION_3;if (capget_wrapper(&hdr, NULL) == -1) {if (errno == EFAULT) {printf("无效指针错误处理正确: %s\n", strerror(errno));}}return 0;
}