在可信位置原子创建临时文件
共享临时目录是其他用户也可能写入的命名空间,并不意味着里面每个文件都公开可读;内容访问仍受文件权限约束。真正危险的假设,是以为选定一个路径,就已经拥有这个名字对应的对象。应原子地创建新对象,并继续使用返回的句柄,而不是信任一个可预测名字,或先检查它不存在、稍后再打开。 名字归属与内容访问是两回事 Linux 的 /tmp 常用模式 1777,即宽松的目录写入、搜索权限,加上 sticky 位。sticky 限制其他用户删除或重命名目录项,却不让现有文件自动保密,也不提前保留尚未创建的名字。文件属主、目录属主、能力及其他访问控制仍然重要。应检查实际环境,不能假定所有操作系统都采用同一路径、挂载方式和权限。 普通写入打开可能跟随预先存在的符号链接。O_CREAT|O_EXCL 拒绝已经存在的最后一个路径名称,包括符号链接。O_NOFOLLOW 则拒绝最后一段是符号链接的情况,但单独使用时不会拒绝既有普通文件,也不保护所有祖先目录。这些是不同契约。应使用可信父目录和适当的临时文件接口,不能把一个标志当成通用路径安全方案。 创建模式也只在真正新建文件时生效。以 O_CREAT 和模式 0600 打开已有文件,不会收紧它原先的权限。随机名字降低碰撞概率,但安全性质来自排他创建,而不只是字符串看起来难以猜测。只生成名字的接口仍留下一段空隙,其他进程可以在真正创建之前占用该名字,因此先检查再创建也不能消除竞争窗口。 位置设置不等于隔离 Python 的 tempfile.mkstemp 安全地创建并打开文件,调用方负责关闭和删除。TemporaryDirectory 提供受限目录和正常退出时的清理。TMPDIR 影响位置选择,却不会自己创建私有目录,也不验证隔离策略。Python 会缓存默认目录选择;如果操作必须使用某个位置,应明确传入 dir=,不要依赖运行中修改环境变量来重新选择。 systemd 的 PrivateTmp= 可以给服务单独的临时文件命名空间,但它改变共享行为,并有平台与 unit 条件,不等同于设置一个环境变量。服务分别使用独立命名空间时,不能依赖跨服务的 /tmp 路径通信。下方本地实验不会启用或验证 systemd 隔离,也不能据此宣称部署已经具有相同隔离边界。 tmpfs 随使用量分配空间,在可用且被允许时可以使用交换空间。没有指定大小时,默认容量上限是物理内存的一半;这是上限,不是挂载时预留的内存。数据分配额度和 inode 数量都可能分别阻止后续工作。/tmp 也不一定挂在 tmpfs 上,因此容量监控应依据实际挂载与负载,不能把目录名字直接当成存储类型。 ...