Skip to content

fix(rm-forbid): convert st_dev to kernel MKDEV encoding before writin… - #160

Open
yuKing123-king wants to merge 1 commit into
DKapture:mainfrom
yuKing123-king:fix/rm-forbid-dev-encoding
Open

yuKing123-king wants to merge 1 commit into
DKapture:mainfrom
yuKing123-king:fix/rm-forbid-dev-encoding

Conversation

@yuKing123-king

Copy link
Copy Markdown
Contributor

修复的 Bug

rm-forbid 的 -p 和 -d 参数写入的设备号编码与 BPF 侧读取的编码不一致,导致所有 major ≠ 0 的文件系统上保护静默失效——被进程占用的文件仍可被删除,工具完全不拦。

根因:dev_old2new() 转换函数已定义(rm-forbid.cpp:36-41),但 parse_args 的 -p 和 -d 两个 case 从未调用它,是死代码。

来源 编码公式 /home(major=253, minor=0)的值
stat() 返回的 st_dev(glibc 编码) (major<<8)|minor 64768
BPF 读取的 s_dev(内核 MKDEV 编码) (major<<20)|minor 264241152

BPF 侧(rm-forbid.bpf.c:71,79)直接读内核的 dir->mnt->mnt_sb->s_dev(MKDEV 编码),用户态存的却是 st_dev(glibc 编码)。两个值对任何 major ≠ 0 的文件系统永远不相等 → rule->dev != fs_dev 恒成立 → return 0(放行删除)。

为什么 /tmp "碰巧能用":/tmp 是 tmpfs,major=0,两种编码公式在 major=0 时结果恰好相等((0<<8)|minor == (0<<20)|minor),所以 /tmp 上保护生效,掩盖了 bug。一旦换到 /home(major=253)、/(major=8)等真实磁盘分区,保护立即静默失效。

对照参考:同仓库的 frtp.cpp:343 正确调用了 dev_old2new(st.st_dev),rm-forbid 是唯一漏掉的工具。

改了哪些地方

仅 filter/rm-forbid.cpp 的 parse_args 函数两行:

// case 'p'(第 176 行)
- rule.dev = fs_dev;
+ rule.dev = dev_old2new(fs_dev);

// case 'd'(第 180 行)
- rule.dev = strtoul(optarg, NULL, 10);
+ rule.dev = dev_old2new(strtoul(optarg, NULL, 10));

get_fs_dev() 的输出(打印给用户看的设备号)保持不变——它打印 glibc 编码值,与 stat -c %d 一致,用户可用 -d <该值> 复现,自洽。dev_old2new() 函数本身无需改动,只是被调用了。

为什么这样修复

  1. 调用已有的转换函数,而非新写逻辑:dev_old2new()(rm-forbid.cpp:36-41)就是为此定义的,使用 gnu_dev_major/gnu_dev_minor 拆分 glibc 编码,再按 (major<<20)|minor 重组为 MKDEV 编码,与 BPF 侧的 MAJOR/MINOR 宏(rm-forbid.bpf.c:27-28)严格对称。它只是没被调用,调用即可。
  2. -p 和 -d 都改:两个 case 写的是同一个 rule.dev 字段,BPF 侧用同一个 s_dev 比对,编码必须统一。-d 接受的值来自 stat -c %d(glibc 编码),同样需要转换,否则 -d 路径的 bug 与 -p 完全相同。
  3. get_fs_dev 打印值不动:打印 glibc 编码(64768)对用户最友好——它和 stat -c %d 一致,用户能理解和复现。转换发生在"存入 rule"这一步,对用户透明。
  4. 两行改动,零回归风险:不碰 BPF 侧、不碰 Rule 结构、不碰 get_fs_dev、不碰过滤逻辑。改动量与 bug 严重性(保护静默失效)成正比。

…g rule

Signed-off-by: Wang Yu <wangyu6@uniontech.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant