我可以让 UNIX 文件权限立即对所有进程生效吗?

jl6*_*jl6 10 permissions file-descriptors

当我使用 更改文件的权限时chmod,现有的文件描述符可以继续在以前的权限下访问该文件。

我可以在权限更改后立即导致那些现有的文件描述符关闭或失败或变得无法使用吗?

Phi*_*ing 11

内核不检查文件描述的权限。它们甚至可以通过fd复制到从未访问过原始文件的其他进程中。

我认为您可以尝试的唯一方法是手动找出具有打开文件描述符的进程,并使用偷偷摸摸的技巧来关闭它们1。有这样一个“狡猾的技巧”的例子是附加一个调试器 ( gdb) 并使用它来关闭 fd。

这是一件非常极端的事情。如果 FD 突然关闭,则无法知道进程的行为方式。在某些情况下,进程可能会将文件映射到内存,因此如果您设法关闭该文件并设法删除任何内存映射,而进程不希望它会因分段错误而崩溃。

更好的是找到哪些进程正在使用文件并手动杀死它们。至少这样你可以让他们很好地关闭而不破坏其他数据。


如评论中提到的1 ,使这项工作的最佳镜头是调用dup2而不是close更改 fd 以指向/dev/null而不是原始文件。这是因为代码不会期望它已经关闭,并且当 fd(数字)被回收时可能会做一些非常奇怪和不安全的事情。

  • 切勿使用调试器关闭 fd;这将产生极其危险的双重关闭/关闭后使用错误,如果应用程序继续运行,它就会**对错误的文件执行操作**。相反,`dup2` 是对它的 `/dev/null` 的引用。 (7认同)
  • @JamesToungman 正如答案的最后一段所描述的那样,这是非常正确的。然而,当进程回收 fds 时会发生什么,存在一个非常具体的安全问题。dup2 技巧可能会导致进程中断,但至少不太可能触发 Web 服务器返回私钥而不是首页。 (2认同)

Bri*_* Bi 6

您不能使现有的文件描述符无效,除非通过 Philip Couling 提到的那些“鬼鬼祟祟的技巧”。但是,您可以以(合理的)便携方式实现类似的效果。

假设您想阻止已经foo打开的进程继续写入foo. 你可以做的是:cp foo foo2; chmod -w foo2; mv foo2 foo。现在任何foo打开旧的进程将继续写入这个文件,它不再被称为foo(比以前少了一个硬链接)。这些进程都不会影响 new foo,因为它们无法打开它进行写入。

如果你想阻止阅读,类似的策略是cp foo foo2; chmod -r foo2; truncate foo; mv foo2 foo. 在这里,旧foo的就地被截断(即,在不删除的情况下减小到零大小),因此已foo打开的进程下次尝试从中读取时将看不到任何内容,并且无法打开新的foo. 但是,这不能保证工作,因为如果任何进程有mmaped foo,那么截断是否实际影响这些映射是不确定的。