news 2026/4/18 5:43:41

硬链接机制中删除文件后的所有权归属问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
硬链接机制中删除文件后的所有权归属问题

一、问题来源如图:

在阅读原文的时候我产生如下疑问:

文中说“因此用户 A 不能删除此文件,只是将该文件的 count 减 1, 然后删除自己目录中的相应目录项。用户 B 仍可以使用该文件。 ”,那用户A删除自己目录中的相应目录项后,此时文件主(文件的所有者)是谁呢?是用户B吗?


二、分析:用户 A 删除操作后的状态演变

1、 初始状态(共享中)

  • 物理层:磁盘上存在一个 Inode(设为 #999),其i_uid为 User A(创建者),i_nlink为 2。

  • 逻辑层

    • User A 的目录项:A_file-> Inode #999

    • User B 的目录项:B_file-> Inode #999

  • 所有权归属:Inode #999 的i_uid字段明确记录为 User A。虽然 User B 有访问路径,但所有权属于 User A。

2、 动作:用户 A 执行删除(unlink

用户 A 决定不再需要该文件,执行rm A_file。此处不仅是简单的删除,而是触发了unlink()系统调用。该调用的执行逻辑如下:

  1. 权限检查:内核检查 User A 是否对User A 的目录拥有写权限。注意,删除文件本质上是修改目录的内容(移除列表项),因此检查的是目录的权限,而非文件的权限 。

  2. 移除目录项:内核从 User A 的目录数据块中抹除A_file这一条目。此时,User A 失去了对 Inode #999 的访问入口。

  3. 递减计数:内核锁定 Inode #999,将其i_nlink值从 2 减至 1。

  4. 生存判定:内核检查i_nlink的新值。

    • 判定逻辑if (i_nlink == 0)则回收 Inode 和数据块;else则保留。

    • 当前结果:由于 Count = 1,内核仅仅更新 Inode 的ctime(状态变更时间),并释放锁。文件数据和 Inode 结构保持原样

3、 终态分析:所有权归属

此时,User A 的目录中已经没有该文件了,文件只存在于 User B 的目录中。关键问题是 :User A 删除了自己的入口,文件所有者会变成 User B 吗?

结论:不会。

解析:

  1. Inode 的持久性unlink操作仅仅修改了i_nlink计数器。它绝不会触碰i_uid(所有者 ID)或i_gid(组 ID)字段。在计算机科学中,未被修改的数据保持原值。因此,Inode 中的所有者信息依然是 User A 。

  2. 所有权转移的机制缺失:UNIX 文件系统没有设计“自动过户”机制。所有权的变更(Change Ownership)是一个特权操作,必须通过chown系统调用显式执行。系统不会因为某人删除了一个链接,就自作主张地将文件过户给另一个人。

  3. 对等性悖论:如果删除链接会导致所有权转移,那么假设有 User A, B, C 三人共享。A 删除了,所有权该给 B 还是 C?由于 B 和 C 的链接是对等的,系统无法做出逻辑判断。因此,所有权必须保持不变,即仍属于最初的创建者 A。

因此可以回答图中的疑问:文中提到“用户 B 仍可以使用该文件”。此时,User B 访问的是 Owner 为 User A 的文件。User B 能否读取或写入,完全取决于 User A 当初设置的RWX权限。如果 User A 设置了“仅所有者可写”,那么 User B 即使是当前唯一的链接持有者,也只能读,不能写。


三、架构背后的安全模型与配额逻辑

理解了“所有权不变”的技术事实后,我们需要探究其背后的设计合理性。为什么操作系统不设计成“谁剩最后谁拥有”?这涉及到 UNIX 的多用户安全模型和资源配额(Quota)管理

1、 磁盘配额(Disk Quota)的结算

在多用户服务器上,系统管理员通常会限制每个用户的磁盘使用量(例如 User A 只能用 10GB)。配额的计算是基于 Inode 的i_uid字段进行的 。

  • 场景推演:如果 User A 创建了一个 5GB 的大文件,硬链接给 User B。

  • 当前状态:该文件占用 User A 的 5GB 配额。

  • 假设所有权转移:如果 User A 删除链接后,所有权自动变为 User B,那么该文件的 5GB 占用量将瞬间计入 User B 的配额。

  • 恶意攻击向量(配额炸弹)

    1. User A 创建巨型垃圾文件。

    2. User A 诱导 User B 创建硬链接(或者 User A 如果有权限写 B 的目录,直接硬链接过去)。

    3. User A 删除自己的链接。

    4. 结果:User B 的磁盘配额被莫名其妙地占满,导致服务拒绝。User A 成功释放了自己的空间并攻击了 B。

为了防止这种“配额嫁接”攻击,UNIX 坚持“谁创建,谁负责”(除非显式转让)的原则。即使 User A 删除了链接,只要文件还存在(被 User B 引用),这个文件占用的磁盘空间依然算在 User A 的账上。这被称为“僵尸文件”或“孤儿所有权”现象——文件存在,但所有者已经没有路径访问它了,却还要为它付账。

2、 权限模型的稳定性

文件的权限(Permission Bits)也是存储在 Inode 中的。如果所有权自动变更,安全边界将崩溃。 例如,User A 创建了一个包含敏感数据的脚本,权限设为700(仅自己可见)。User A 将其硬链接到公共目录以便临时使用。使用后 User A 删除了公共目录的链接。如果此时所有权转移给了系统中的其他用户(假设存在某种竞态条件),那么敏感数据就可能泄露。保持所有权为 User A 确保了无论文件在哪里被访问,访问控制列表(ACL)始终如一。


四. 用户 B 的操作困境与解决方案

在 User A 删除链接后,User B 此时持有的是一个“属于 User A 的文件”。这对 User B 意味着什么?

1、读写权限受限

User B 对该文件的操作权限受到 Inode 中i_mode字段的严格限制:

  • 如果 User A 设置了chmod 644(所有者读写,他人只读):User B 只能读取文件,无法修改。即使 User B 想删除这个文件来释放空间,他也只能删除自己目录下的这个“入口”,而不能修改文件内容。

  • 如果 User A 设置了chmod 666(全员可写):User B 可以修改文件内容。任何修改都会直接作用于磁盘上的数据块。如果 User A 之后通过某种手段(如debugfs或恢复工具)找回了文件,会看到 User B 修改后的版本。

2、编辑器的行为差异(Edit vs Replace)

这是硬链接使用中最容易产生误解的地方。当 User B 试图用文本编辑器(如 Vim, Nano, VS Code)编辑这个文件时,结果取决于编辑器的保存策略 :

  • 策略一:就地写入(In-place Edit)

    • 编辑器打开文件,读取内容,用户修改。

    • 保存时,编辑器打开原路径,将新数据写入原 Inode。

    • 结果:Inode 编号不变,所有者依然是 User A。User B 必须有写权限才能成功。

  • 策略二:原子替换(Atomic Save / Unlink-and-Create)

    • 编辑器写入一个临时文件(新 Inode,所有者为当前操作者 User B)。

    • 编辑器执行rename(temp_file, original_filename)。这会隐含地执行unlink原文件,并用新文件取代之。

    • 结果:原 Inode(属于 User A)的引用计数减为 0,被系统回收。目录项现在指向一个新的 Inode,这个新 Inode 由 User B 创建,因此所有者变成了 User B

结论:如果 User B 使用“原子替换”策略的编辑器修改文件,表面上看起来所有权变了,但实际上是 User B 悄悄地把 User A 的旧文件替换成了一个内容相同的新文件。旧的链接关系已经被切断。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:09:05

结合真实案例讲述Miniconda如何提升团队协作效率

Miniconda 如何重塑团队协作:从“在我机器上能跑”到可复现的工程实践 在一次紧急的模型评审会上,某 AI 团队演示图像分类项目时,系统突然报错:“ModuleNotFoundError: No module named torchvision”。奇怪的是,开发者…

作者头像 李华
网站建设 2026/4/16 13:28:54

SSH multiplexing提升频繁连接Miniconda服务器效率

SSH Multiplexing 提升频繁连接 Miniconda 服务器效率 在现代 AI 开发中,远程服务器几乎成了实验室和工程团队的“第二桌面”。你可能正在本地写代码,下一秒就要把脚本传到远端跑训练;或者刚改完模型参数,就想立刻进 Jupyter 看看…

作者头像 李华
网站建设 2026/4/16 23:03:31

AMD Ryzen处理器底层调试实战:从零掌握硬件参数精准调控

你是否曾经遇到过这样的困扰:明明拥有强大的AMD Ryzen处理器,却感觉性能没有完全释放?面对复杂的BIOS设置和硬件参数,不知从何入手进行深度优化?今天,我们将带你深入了解这款专业的底层调试工具&#xff0c…

作者头像 李华
网站建设 2026/4/16 13:41:40

FFXIV终极动画跳过插件:快速配置与一键优化完整指南

FFXIV终极动画跳过插件:快速配置与一键优化完整指南 【免费下载链接】FFXIV_ACT_CutsceneSkip 项目地址: https://gitcode.com/gh_mirrors/ff/FFXIV_ACT_CutsceneSkip 还在为重复观看副本动画而烦恼吗?FFXIV_ACT_CutsceneSkip插件专门解决这一痛…

作者头像 李华
网站建设 2026/4/17 7:51:06

免费解锁英雄联盟全皮肤:LeagueSkinChanger完整使用指南

免费解锁英雄联盟全皮肤:LeagueSkinChanger完整使用指南 【免费下载链接】LeagueSkinChanger Skin changer for League of Legends 项目地址: https://gitcode.com/gh_mirrors/le/LeagueSkinChanger 想要在英雄联盟中体验所有英雄的皮肤却不想花费点券&#…

作者头像 李华
网站建设 2026/4/16 17:20:20

HTML页面调用Python脚本:Miniconda-Python3.10支持Flask快速部署

HTML页面调用Python脚本:Miniconda-Python3.10支持Flask快速部署 在数据科学与Web开发的交汇处,一个常见但关键的需求浮出水面:如何让用户通过浏览器界面,轻松触发后台复杂的Python逻辑?比如上传一张图片进行AI推理、…

作者头像 李华