请求模式按普通 umask 过滤或默认 ACL 继承分支;既有 inode 使用独立路径。

umask 过滤新建权限,默认 ACL 会改变规则

进程的 umask 在普通模式位创建规则下,为新文件和目录移除权限位。应用先提供请求模式,掩码再限制这份请求。它既不是完整访问策略,也不会重写所有既有文件。如果父目录具有默认访问控制列表,创建计算方式还会改变,因此只检查进程掩码,可能无法准确预测最后得到的权限。排查时需要同时看到应用请求和目录环境。 坏掉的样子 没有默认 ACL 时,普通权限结果是请求模式与 umask 按位取反后的值进行按位与。例如请求 0666、掩码 0022,得到 0644。这个计算不是算术减法:相同掩码下请求 0600,仍然得到 0600。应用没有请求执行权限时,宽松掩码也不会主动添加执行位;掩码负责移除,而不是凭空授予应用未请求的普通权限。 限制严格的 umask 不会修复已经存在的全员可写文件。打开并截断该文件,会改变内容,却保留既有模式。后续 chmod 也可以不受当前掩码限制地扩大权限。因此,把 umask 当作权限永远不能超过的上界,会遗漏既有文件与之后权限修改两类情况。必须区分文件首次创建,以及此后围绕同一 inode 发生的操作。 父目录具有默认 ACL 时,Linux 从它派生新对象的访问 ACL,再按应用请求模式限制权限,不再按普通方式应用进程 umask。因此,即使创建者掩码是 0077,共享目录里仍可能生成组可访问文件。遇到与预期不同的模式时,应检查继承的 ACL,而不能只看到严格掩码就断言内核没有遵守权限设置。 普通掩码与默认 ACL 继承是不同创建分支。已有文件截断与后续 chmod 另行处理;案例属于实验预期。 快速验证 把脚本保存为 mask.py,在安装 Python 3 和 setfacl 的 Linux 环境中运行 python3 mask.py。应使用获准且没有既有默认 ACL 的临时目录基址,所在文件系统须支持默认 ACL,并启用断言。历史文章报告 Python 3.11.2、acl 2.3.1,以及先在 tmpfs 被拒绝、再在 ext4 执行的过程;但未找到原始日志,本轮没有更改存储或重跑。该次拒绝不代表所有 tmpfs 配置都不支持 ACL: ...

十月 9, 2027 · 2 分钟 · XB Field Notes
可执行文件属主经 exec 条件检查影响有效与保存 UID,真实 UID 保持不变。

Setuid 在 exec 时改变有效身份

Linux 可执行文件上的 setuid 位,可以在 exec 成功时把进程的有效用户 ID 改为文件属主的 ID。它不会把进程全部凭据都替换成属主的登录身份。特权辅助程序因此能够代表另一个账户完成受控操作,但输入处理和特权持续时间都会成为安全边界的一部分。模式位本身既不能证明身份转换已经发生,也不能证明这个辅助程序安全。 文件位与进程凭据分开观察 通常的 set-user-ID 转换会改变有效 UID,再将结果复制到保存的 set-user-ID;真实 UID 保持不变。组凭据是另一套状态:setuid 不会自动装入文件属主的附加组。Linux 还存在文件系统身份和能力集合,因此真实、有效与保存 UID 是有用的观察,却不是权限的完整描述。不能看到有效身份变成某个账户,就假设已经拥有该账户登录会话的全部上下文。 应检查实际部署的文件,不要推断整个发行版都采用同一权限。用于修改密码的特权程序,在容器或定制镜像里可能有不同安装方式。属主执行位位置的小写 s 表示同时具备 setuid 和属主执行位,大写 S 则表示存在 setuid 但没有那个执行位。两种显示都不能替代属主核验、目标文件核验,以及对真实启动上下文的检查。 执行环境可以抑制转换 Linux 文档列出了 no_new_privs、nosuid 挂载和被跟踪等条件,它们可能抑制特权转换;某些文档记录的组合也可能直接让执行失败。文件能力同样受到执行约束。不能为了让演示成功,就关闭这些保护。应确定目标路径与调用进程实际适用哪些政策,如实说明限制,而不是把受保护环境当作必须修复的故障。 Linux 忽略解释器脚本上的 set-user-ID 与 set-group-ID 位。因此,把原生辅助程序改成脚本并保留模式,不会保留原先的提权行为。给通用解释器增加特权也不是安全替代方案。特权程序另外启动的可执行文件,还可能主动重置凭据,所以运行独立的 id 命令,不一定忠实显示原辅助程序内部的身份。观测点必须与要验证的进程一致。 ...

十月 2, 2027 · 2 分钟 · XB Field Notes
sticky 目录限制同级用户删除目录项;内容写入走独立路径,由文件模式决定。

sticky bit 限制共享目录中的删除操作

Linux 目录上的 sticky bit,为删除或重命名目录项增加所有权限制。它常与宽松的目录写入、搜索权限一起使用,让多个用户能够创建临时文件,又不能任意删除彼此的条目。普通目录权限检查和 sticky 所有权检查都需要满足;sticky 是额外条件,不会替代正常访问控制,也不能只凭这一位判断整个目录里的数据是否安全。 坏掉的样子 没有 sticky 时,用户只要具备目录所需的写入与搜索权限,通常就能删除另一个用户的文件,即使文件模式完全不允许内容访问。unlink 改变的是目录里的名字与对象关系,不要求调用者能够读取或覆盖文件内容。因此,在广泛可写目录中把文件设为 000,并不能单独保护该路径不被他人删除;应分别检查父目录和文件自身的规则。 启用 sticky 后,普通用户还需要拥有该条目或包含它的目录,才能执行相关删除。具有适当 CAP_FOWNER 能力的特权进程,可以绕过这项所有权限制。因此 sticky 约束的是具体权限模型下的同级用户,并不抵御所有管理员,也不保护文件免受目录所有者删除。把它描述为绝对隔离,会夸大真实保证。 sticky 不阻止本来被允许的内容访问。一个用户可能无法 unlink 某个 0666 文件,却仍然可以读取或覆盖它。新建子目录也不会自动继承父目录的 sticky 位。混淆路径保护、内容隐私和继承,会让共享目录树表现出与顶层看起来完全不同的行为,需要沿实际数据位置检查,而不是只看根部权限字符串。 sticky 限制目录项删除,并有所有权与能力例外。文件模式另行控制内容;实验结果是预期,不是新观察。 快速验证 把脚本保存为 sticky.py,只在获准的一次性 Linux 环境中启用断言运行 python3 sticky.py。控制进程需要 root 权限以分配三个数字身份并启动普通子进程,不会创建账号。历史文章报告 Linux 6.12.76 与 Python 3.11.2,但未找到原始日志,本轮也没有重跑。文件系统所有权、UID 映射与子进程能力必须符合预期权限模型,不能只看数字身份: ...

十月 1, 2027 · 2 分钟 · XB Field Notes