说明
最近发现vArmor-ebpf增加一个pstrace的功能,学习其实现原理。具体参见 ptrace-confine
内核实现
v_ptrace
1 | struct { |
定义了v_ptrace用来保存ptrace的规则。
函数get_ptrace_rule获取对应的命名空间的ptrace的规则。
ptrace_access_check
1 | SEC("lsm/ptrace_access_check") |
有关ptrace_access_check原函数的实现:
1 | static int apparmor_ptrace_access_check(struct task_struct *child, |
针对mode的值,以下是可能的选项及其含义:
PTRACE_MODE_READ(0x01):表示读取另一个任务的状态。PTRACE_MODE_ATTACH(0x02):表示附加到另一个任务。
所以通过(mode & PTRACE_MODE_READ) ? AA_PTRACE_READ : AA_PTRACE_TRACE),就可以知道当前pstrace操作类型。
varmor_ptrace_access_check函数根据传入的ptrace访问规则和请求的权限,对当前任务和child任务的挂载命名空间进行比较,并根据规则中的标志位决定是否允许访问。这个函数用于在ptrace_access_check函数中进行权限检查,以确定是否允许使用ptrace`系统调用来追踪或读取另一个任务的状态。
所以关键实现是看ptrace_permission_check函数具体实现。
ptrace_permission_check
1 |
|
通过
rule >> 32和(u32)(rule & 0xffffffff),分别得到permissions和flags。permissions & request_permission如果在permissions中包含了request_permission的权限,则进一步判断。- 如果标志位(
flags)中包含了GREEDY_MATCH,表示拒绝所有任务,函数返回false表示访问被拒绝。 - 如果标志位中包含了
PRECISE_MATCH,表示只拒绝容器外的任务,那么如果当前任务的挂载命名空间ID与child任务的挂载命名空间ID不相等,函数返回false表示访问被拒绝。 - 如果以上判断都通过,表示访问被允许,函数返回
true。
这个函数根据传入的ptrace访问规则和请求的权限,对当前任务和child任务的挂载命名空间进行比较,并根据规则中的标志位决定是否允许访问。这个函数用于在ptrace_access_check函数中进行权限检查,以确定是否允许使用ptrace系统调用来追踪或读取另一个任务的状态。
用户态实现
PtraceContent
在apis/varmor/v1beta1/armorprofile_types.go中添加了相关的规则。

定义了PtraceContent结构体,包含了Permissions和Flags,对应内核态判断标准得两个参数。
BpfContent结构体是所有规则类型的合集,在其中增加了PtraceContent结构体,后面就可以通过BpfContent设置pstrace的规则。
rule
pkg/lsm/bpfenforcer/profile.go

将pstrace相关的规则添加到V_ptrace规则列表中。
在添加规则时通过rule := uint64(bpfContent.Ptrace.)<<32 + uint64(bpfContent.Ptrace.Flags)将Permissions和Flags合并成为rule,这种方式和内核态中代码是对应的。
1 | u32 permissions = rule >> 32; |
generateRawPtraceRule
internal/profile/bpf/bpf.go中增加了generateRawPtraceRule()函数方法。

这个函数是将varmor.PtraceRule转换为varmor.BpfContent格式。两者对应的格式是:
1 | type PtraceRule struct { |
将permission类型(trace,read,traceby,readby)转换为AaPtraceTrace等类型的数字。
将rule类型(StrictMode和其他模式)转换为GreedyMatch(0x00000002)和PreciseMatch(0x00000001)
所以,当规则设定使用字符串表示,函数generateRawPtraceRule()转换为对应的数字类型,方便后面转换为rule。
org_varmorpolicies
crd.varmor.org_varmorpolicies.yaml中也增加了相关的规则格式和说明
1 | ptrace: |
crd.varmor.org_varmorpolicies.yaml定义了一个 Kubernetes 自定义资源定义(Custom Resource Definition,CRD),用于扩展 Kubernetes API 并引入名为 varmorpolicies.crd.varmor.org 的新资源类型。
properties定义了两个属性,分别是permissions和strictModepermissions是一个字符串数组类型,可选值包括trace, traceby,read, readbystrictMode是布尔类型
这个配置的设置和前面在generateRawPtraceRule()函数中解析PtraceRule就对应上了。
总结
通过 ptrace-confine中添加了ptrace功能的相关实现,可以很好地了解在用户态对于规则的解析和运用。
参考
https://github.com/bytedance/vArmor-ebpf/commit/b539731a641283dbb48ff1e7e569fe521b717d41