【问题标题】:Change UID/GID only of one thread in Linux在 Linux 中仅更改一个线程的 UID/GID
【发布时间】:2023-03-18 16:20:02
【问题描述】:

有没有办法只更改多线程进程中一个线程的 UID/GID?

这样做的原因是编写一个文件服务应用程序 - 除非调用者的 uid/gid 设置为正确的用户,否则不会强制执行 ACL 和配额,没有使用正确的 uid/gid 创建新文件/目录等.

网络应用程序通常可以在开始时自己 fork() 并在单独的进程中处理每个用户请求。如果需要共享数据,它必须通过某种共享内存。但是,例如FUSE(Linux 用户文件系统)默认使用多线程,结合 python 绑定,尝试使用分叉模型是不切实际的。

整个进程的“一致”UID 似乎符合 POSIX 标准,但是旧的 Linux 不遵循 POSIX 并允许不同线程使用不同的 uid。新内核似乎遵循 POSIX,有什么方法可以允许旧的“损坏”行为吗?

【问题讨论】:

    标签: linux pthreads setuid


    【解决方案1】:

    特定于 Linux 的 setfsuid() / setfsgid() 是每个线程而不是每个进程。它们专为此用例(文件服务器)而设计。

    请注意,access() 仍将使用真实的 uid 和 gid 检查访问权限 - 这是设计使然(它旨在回答问题“运行此二进制文件的用户是否有权访问此文件” )。对于setfsuid() / setfsgid() 情况,您应该尝试请求的操作并检测由于当时缺乏权限而导致的失败。

    【讨论】:

    • 这样更好——我检查过并惊讶地发现它们确实是每个线程的。这可能是首选方式。但是 - 我没有测试它的原因是 quota() 和 access() 不起作用。其他事情确实有效 - 所以这可能是 Linux 错误。
    • 是的,这听起来确实像一个错误,因为 sys_setfsuid() 的内核代码中的 cmets 特别提到了 access()...
    • @Ondrej,请发布代码(或指向它的链接),证明 fsuid 与其他 UID/GID 构造不同,是每个线程而不是每个进程。还请指定您的内核和 glibc 版本,以及您的线程实现(NPTL、LinuxThreads、OndrejThreads 等)。
    • pilcrow,我使用 python 和线程做了一些非常简单的测试。但是:quota() 有效,但是在检查之前必须放弃一些功能(我认为是 CAP_RESOURCE)。 access() 不起作用,根据 POSIX,“不应该”起作用。对我来说,这似乎是 POSIX 中的一个错误(我发现的第二个错误),而且似乎 Linux 中的任何人都不会有兴趣更改它:(
    【解决方案2】:

    要仅更改一个线程的 uid,您需要直接使用系统调用:syscall(SYS_setresuid, ...); libc 函数 setresuid() 将为所有线程同步它(使用它发送给所有线程的信号)!

    【讨论】:

      猜你喜欢
      • 2016-06-17
      • 2017-08-29
      • 2011-07-14
      • 2020-11-11
      • 2021-01-26
      • 2018-11-28
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多