说明
最近发现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
和strictMode
permissions
是一个字符串数组类型,可选值包括trace, traceby,read, readbystrictMode
是布尔类型
这个配置的设置和前面在generateRawPtraceRule()
函数中解析PtraceRule
就对应上了。
总结
通过 ptrace-confine中添加了ptrace
功能的相关实现,可以很好地了解在用户态对于规则的解析和运用。
参考
https://github.com/bytedance/vArmor-ebpf/commit/b539731a641283dbb48ff1e7e569fe521b717d41