【问题标题】:Is this possible to switch the user and group of an application thread?这是否可以切换应用程序线程的用户和组?
【发布时间】:2018-01-05 22:18:39
【问题描述】:

我想用 Rust 构建一个小型 Web 应用程序,它应该能够代表用户读取和写入文件。用户应使用其 UNIX 凭据进行身份验证,然后只能读取/写入他们有权访问的文件。

我的第一个想法,对我来说似乎也是最安全的,是切换应用程序线程的用户上下文并在那里执行所有读/写操作。这可能吗?

如果这是可能的,性能会是什么样子?我会假设每次请求进入时产生一个操作系统线程可能会产生非常高的开销。有没有更好的方法来做到这一点?

我真的不想以 root 身份运行我的整个应用程序并手动检查权限。

【问题讨论】:

    标签: multithreading unix rust file-permissions setuid


    【解决方案1】:

    在 GNU/Linux 上,不能只为进程的单个线程切换 UID 和 GID。 Linux 内核维护每个线程的凭据,但 POSIX 要求每个进程使用一组凭据:POSIX setuid 必须更改所有线程的 UID,或者不更改。 glibc 不遗余力地模拟 POSIX 行为,尽管这非常困难。

    您必须为每个请求创建一个全新的进程,而不仅仅是一个新线程。在 Linux 上创建进程非常便宜,但它仍然可能是一个性能问题。您可以保留一个进程池,以避免重复创建进程的开销。另一方面,很多年前,很多网站(包括一些相当大的网站)都使用 CGI 来生成网页,并且您可以通过简单的设计走得比较远。

    【讨论】:

      【解决方案2】:

      我认为@Florian 在他原来的回答中倒退了。 man 2 setuid

      C 库/内核差异

      在内核级别,用户 ID 和组 ID 是每个线程的属性。但是,POSIX 要求进程中的所有线程 共享相同的凭据。 NPTL 线程实现句柄 通过为各种 改变进程的系统调用 UID 和 GID。这些封装函数(包括 setuid() 的封装函数)采用了一种基于信号的技术来确保当一个 线程更改凭据,进程中的所有其他线程 也改变他们的凭据。有关详细信息,请参阅 nptl(7)。

      由于 libc 会在整个过程中执行信号舞蹈,因此您必须执行直接系统调用来绕过它。

      请注意,这是特定于 linux 的。大多数其他 unix 变体似乎确实在内核级别遵循 posix,而不是在 libc 中模拟它。

      【讨论】:

      • 我澄清了我的回答。对于 GNU/Linux,我指的是带有 GNU (glibc) 用户空间的 Linux 内核。其他 libcs​​ 的行为可能不同。 glibc 可能无法通过直接系统调用对 UID/GID 更改做出良好反应。
      猜你喜欢
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      • 1970-01-01
      • 2021-04-18
      • 2013-10-11
      • 1970-01-01
      相关资源
      最近更新 更多