BPF_PROG_TYPE_CGROUP_SYSCTL¶
本文件描述了 BPF_PROG_TYPE_CGROUP_SYSCTL 程式型別,該型別為 sysctl 提供 cgroup-bpf 鉤子。
該鉤子必須附加到 cgroup,並且每當該 cgroup 中的程序嘗試從 proc 中的 sysctl 旋鈕讀取或寫入時都會被呼叫。
1. 附加型別¶
必須使用 BPF_CGROUP_SYSCTL 附加型別將 BPF_PROG_TYPE_CGROUP_SYSCTL 程式附加到 cgroup。
2. 上下文¶
BPF_PROG_TYPE_CGROUP_SYSCTL 提供從 BPF 程式訪問以下上下文的功能:
struct bpf_sysctl {
__u32 write;
__u32 file_pos;
};
write指示 sysctl 值是正在讀取 (0) 還是正在寫入 (1)。此欄位是隻讀的。file_pos指示訪問 sysctl 時的檔案位置(讀取或寫入)。此欄位是讀寫的。寫入此欄位會設定 sysctl proc 檔案中read(2)將從中讀取或write(2)將寫入的起始位置。例如,即使使用者空間在file_pos > 0時呼叫write(2),將零寫入此欄位也可用於透過bpf_sysctl_set_new_value()覆蓋整個 sysctl 值。將非零值寫入此欄位可用於從指定的file_pos開始訪問 sysctl 值的一部分。並非所有 sysctl 都支援在file_pos != 0時進行訪問,例如,對數字 sysctl 條目的寫入必須始終在檔案位置0。另請參閱kernel.sysctl_writes_strictsysctl。
有關如何訪問上下文欄位的更多詳細資訊,請參閱 linux/bpf.h。
3. 返回碼¶
BPF_PROG_TYPE_CGROUP_SYSCTL 程式必須返回以下返回碼之一:
0表示“拒絕訪問 sysctl”;1表示“繼續訪問”。
如果程式返回 0,使用者空間將從 read(2) 或 write(2) 獲得 -1,並且 errno 將設定為 EPERM。
4. 輔助函式¶
由於 sysctl 旋鈕由名稱和值表示,sysctl 特定的 BPF 輔助函式專注於提供對這些屬性的訪問:
bpf_sysctl_get_name():將/proc/sys中可見的 sysctl 名稱獲取到 BPF 程式提供的緩衝區中;bpf_sysctl_get_current_value():將 sysctl 當前持有的字串值獲取到 BPF 程式提供的緩衝區中。此輔助函式在從 sysctlread(2)和向 sysctlwrite(2)時都可用;bpf_sysctl_get_new_value():在實際寫入發生之前,獲取當前正在寫入 sysctl 的新字串值。此輔助函式只能在ctx->write == 1時使用;bpf_sysctl_set_new_value():在實際寫入發生之前,覆蓋當前正在寫入 sysctl 的新字串值。sysctl 值將從當前的ctx->file_pos開始被覆蓋。如果整個值需要被覆蓋,BPF 程式可以在呼叫此輔助函式之前將file_pos設定為零。此輔助函式只能在ctx->write == 1時使用。透過此輔助函式設定的新字串值,核心會像處理使用者空間傳入的等效字串一樣進行處理和驗證。
BPF 程式以與使用者空間在 proc 檔案系統中相同的方式(即作為字串)看待 sysctl 值。由於許多 sysctl 值表示一個整數或一個整數向量,因此可以使用以下輔助函式從字串中獲取數值:
bpf_strtol():將字串的初始部分轉換為長整數,類似於使用者空間的 strtol(3);bpf_strtoul():將字串的初始部分轉換為無符號長整數,類似於使用者空間的 strtoul(3);
有關此處描述的輔助函式的更多詳細資訊,請參閱 linux/bpf.h。
5. 示例¶
有關用 C 語言編寫的 BPF 程式示例,該程式訪問 sysctl 名稱和值,解析字串值以獲取整數向量,並使用結果決定是否允許或拒絕訪問 sysctl,請參閱 test_sysctl_prog.c。
6. 注意事項¶
BPF_PROG_TYPE_CGROUP_SYSCTL 旨在用於受信任的根環境,例如監控 sysctl 使用情況或捕獲在單獨 cgroup 中以 root 身份執行的應用程式嘗試設定的不合理值。
由於 task_dfl_cgroup(current) 在 sys_read / sys_write 時被呼叫,它可能返回與 sys_open 時不同的結果,即在 proc 檔案系統中開啟 sysctl 檔案的程序可能與嘗試從中讀取/寫入的程序不同,並且這兩個程序可能在不同的 cgroup 中執行,這意味著 BPF_PROG_TYPE_CGROUP_SYSCTL 不應作為限制 sysctl 使用的安全機制。
與任何 cgroup-bpf 程式一樣,如果執行在 cgroup 中的應用程式以 root 身份執行,並且不應允許其分離/替換管理員附加的 BPF 程式,則應格外小心。