【问题标题】:Determine if path is inside directory确定路径是否在目录内
【发布时间】:2020-11-24 11:44:15
【问题描述】:

在我的应用程序中,我试图检查路径是否在特定目录中。例如,我希望我的应用程序的某些部分不能访问路径 /x/y/z 中的文件。我不能使用传统的文件权限,因为应用程序的其他部分应该能够访问这些文件。

一些互联网资源建议使用realpath 来首先规范化路径,即解析.. 的所有符号链接和实例(例如1、2)。 但是,似乎不可能在没有竞争条件 (TOCTOU) 的情况下执行路径解析,然后是 open。

char *resolved = realpath("/my/potentially/dangerous/path.txt", NULL);
// someone changes any part of the path to a symlink to something else   <--- race condition
if (check_path(resolved)) {
    //                                                                   <--- race condition
    int fd = open(resolved, O_RDONLY);
}

我是否忽略了某些东西,或者 POSIX(和 Linux)是否没有提供任何方法来在没有竞争条件的情况下执行此类操作?

【问题讨论】:

  • 您的应用程序的这些孤立部分真的应该能够访问某个目录下的任何除了所有内容吗?你能不能把你的应用程序分成两个进程,将其中一个进程chroot到例如一个临时目录,然后在该目录下挂载它应该能够访问的所有内容?
  • 您要防范什么?这似乎是classic XY problem。你有一些未知的问题,你已经决定如何解决它,你问的是解决方案,而不是你的实际问题。
  • 这是一种进程内隔离(类似于vahldiek.github.io/project/erim),其中应用程序的某些部分是受信任的,而其他部分则不是。所以前提是只有一个进程。

标签: c posix chroot realpath


【解决方案1】:

“openat2”(仅限 Linux)怎么样?

一旦你有了一个文件描述符,看 man open

说明:

文件描述符是对打开文件描述的引用;这 如果路径名随后被删除或引用不受影响 修改为引用不同的文件。

【讨论】:

  • openat2() 不是 POSIX。
  • @Andrew Henle True,但并没有特别要求 Posix。
  • POSIX 标签从发布的那一刻起就在问题上。
  • 您的意思是先解决它,然后用 RESOLVE_NO_SYMLINKS 打开它?如果失败了再试一次?我实际上很好,因为它不是 POSIX,但是,它是在 Linux 5.6 中引入的。纯 POSIX 或旧版 Linux 没有解决方案吗?
  • @user2737037 解析标志还不够吗?好的,realpath 为您提供了一个绝对路径名,但您仍然需要检查该文件的权限。你不能用解析标志来描述你想要达到的目标吗?基本上是一步而不是两步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 2017-04-03
  • 1970-01-01
相关资源
最近更新 更多