Files
container-from-scratch/src/capabilities.c
T
XingfenD f21cbe0574 Add comments to all source and header files
- include/container.h: document struct fields and constants
- src/main.c: explain argument parsing, clone flow, parent/child roles
- src/mount.c: describe 6-step mount isolation process
- src/cgroup.c: explain cgroup data structures and resource setup/cleanup
- src/capabilities.c: document capability drop (bounding + inheritable)
- src/seccomp.c: explain each seccomp rule's security purpose
- src/userns.c: describe parent-child sync and uid_map/gid_map format
- src/hostname.c: document tarot card random naming scheme
2026-07-23 15:48:33 +08:00

72 lines
2.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* capabilities.c — Linux Capabilities 权限收窄模块
*
* 将 root 的"万能权限"拆解为 30+ 个细粒度的 capability,
* 本模块 drop 掉容器不需要的 20 个危险 capability,
* 只保留最小权限集。
*
* 两步操作:
* 1. prctl(PR_CAPBSET_DROP) — 从 bounding set 移除,子进程也无法获取
* 2. cap_set_flag(CAP_INHERITABLE, CAP_CLEAR) — 清除 inheritable 集
*/
#include <stdio.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <linux/capability.h>
#include "capabilities.h"
int capabilities(void)
{
fprintf(stderr, "=> dropping capabilities...");
/* 需要 drop 的危险 capability 列表 */
int drop_caps[] = {
CAP_AUDIT_CONTROL, /* 修改审计日志 */
CAP_AUDIT_READ, /* 读取审计日志 */
CAP_AUDIT_WRITE, /* 写入审计日志 */
CAP_BLOCK_SUSPEND, /* 阻止系统挂起 */
CAP_DAC_READ_SEARCH, /* 绕过文件读权限检查 */
CAP_FSETID, /* 设置 setuid/setgid 位 */
CAP_IPC_LOCK, /* 锁定共享内存 */
CAP_MAC_ADMIN, /* 修改 MAC 策略(如 SELinux) */
CAP_MAC_OVERRIDE, /* 覆盖 MAC 策略 */
CAP_MKNOD, /* 创建设备文件 */
CAP_SETFCAP, /* 设置文件 capability */
CAP_SYSLOG, /* 操作内核日志 */
CAP_SYS_ADMIN, /* 挂载、namespace 等大量特权操作 */
CAP_SYS_BOOT, /* 重启系统 */
CAP_SYS_MODULE, /* 加载/卸载内核模块 */
CAP_SYS_NICE, /* 调整进程优先级 */
CAP_SYS_RAWIO, /* 直接 I/O 端口操作 */
CAP_SYS_RESOURCE, /* 修改资源限制 */
CAP_SYS_TIME, /* 修改系统时间 */
CAP_WAKE_ALARM /* 设置唤醒闹钟 */
};
size_t num_caps = sizeof(drop_caps) / sizeof(*drop_caps);
/* 第一步:从 bounding set 中移除
* bounding set 限制了进程能获取的最大能力集,
* 一旦 drop,即使后续 execve setuid 程序也无法获取 */
fprintf(stderr, "bounding...");
for (size_t i = 0; i < num_caps; i++) {
if (prctl(PR_CAPBSET_DROP, drop_caps[i], 0, 0, 0)) {
fprintf(stderr, "prctl failed: %m\n");
return 1;
}
}
/* 第二步:从 inheritable set 中清除
* inheritable set 控制 execve 后哪些 capability 可被继承 */
fprintf(stderr, "inheritable...");
cap_t caps = NULL;
if (!(caps = cap_get_proc())
|| cap_set_flag(caps, CAP_INHERITABLE, num_caps, drop_caps, CAP_CLEAR)
|| cap_set_proc(caps)) {
fprintf(stderr, "failed: %m\n");
if (caps) cap_free(caps);
return 1;
}
cap_free(caps);
fprintf(stderr, "done.\n");
return 0;
}