Skip to content

The mbatchd process umask was permanently changed by mistake #116

Description

@tczz88888

问题

mbatchd 的 initSubmitReq()(lsbatch/daemons/mbd.job.c)在初始化 submitReq 模板时写了这样一行:
jobBill->umask = umask(0077);
意图是「读出当前 umask 并记录到字段里」,但 umask() 是读写一体的系统调用——它返回旧值的同时会把进程 umask 设成传入的新值。这行只取了返回值,没有把 umask 改回去,于是 mbatchd 的进程 umask 被永久改成 0077。
并且被捕获的那个值其实从未被使用:getMergeSubReq() 紧接着调用的 mergeSubReq() 会执行 to->umask = old->umask;,用原作业请求里的值(来自提交用户的真实 umask)把它覆盖掉。也就是说,这一行唯一的实际效果就是破坏进程 umask。
代码出自 2011-06-05 的 openlava 首次提交(58eb4746),并非 volclava 引入。

调用链

有两条路径会走到 initSubmitReq(),它们是同一条链,区别只在于触发时机。
一、运行时:用户执行 bmod。只有对 PEND 作业的 bmod 才会走到这里;对 RUN 作业的 bmod 会在更早的检查处被拒绝,不触发本问题。
do_modifyReq
└─ modifyJob() mbd.job.c:5732
└─ modifyAJob()
└─ getMergeSubReq() mbd.job.c:6270
├─ initSubmitReq() mbd.job.c:8209 ← umask(0077),不恢复
└─ mergeSubReq() mbd.job.c:7358
└─ to->umask = old->umask; ← 覆盖掉刚捕获的值
二、启动时:replay 事件日志。这是「重启无法恢复」的原因。main() 里 umask(022) 排在 minit() 之前,而 replay 发生在 minit() 内部,所以只要 lsb.events 里还留着 JOB_MODIFY2 记录,replay 就会重新把 umask 打成 0077。
main()
├─ umask(022) mbd.main.c:433 ← 先设为 022
└─ minit(FIRST_START) mbd.main.c:444
└─ init_log()
└─ replay lsb.events
└─ replay_modifyjob2() ← 遇到 JOB_MODIFY2 事件
└─ modifyJob() ← 同上,再次 umask(0077)

影响

只要执行过一次 bmod,mbatchd 的 umask 就会变成 0077,并且永远不会恢复——重启 mbatchd 也没用,因为 replay 事件时对 bmod 的事件同样会执行 modifyJob。后果是 mbatchd 之后创建的文件,默认权限从 0644 变成 0600,需要 chmod。
一个不需要任何新增代码就会踩到的场景是守护进程日志。ls_syslog() 每次写入前都会 lstat 日志文件,发现不存在就用 fopen(logfile, "a") 重建,而这条重建路径没有 chmod(初始化路径 openLogFile() 是有的)。因此只要做过 bmod、又轮转或删除过 mbatchd.log,重建出来的日志文件就是 0600,管理员账号反而读不了自己的守护进程日志。
实测对照,操作完全相同(删除日志文件后等待 mbatchd 重建),唯一变量是 umask:

事件日志中有无 bmod 记录 mbatchd umask 重建后的日志文件 volclava 能否读取
无 0022 -rw-r--r-- 可读
有 0077 -rw------- Permission denied

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions