【问题标题】:pthread_setname_np() when capabilities are set设置功能时的 pthread_setname_np()
【发布时间】:2017-08-02 16:07:03
【问题描述】:

我用 man pthread_setname_np 编译了示例程序

g++ -pthread  example.cpp

我设置了我的程序 a.out 的 cap_net_raw 能力。

sudo setcap 'cap_net_raw=+eip' a.out

令人惊讶的是程序在执行时失败了:

$./a.out
Created a thread. Default name is: a.out
pthread_setname_np: Permission denied

当我删除它起作用的功能时..

$sudo setcap 'cap_net_raw=-eip' a.out
$./a.out
Created a thread. Default name is: a.out
The thread name after setting it is THREADFOO.
Done

所以对我来说,当我添加一项功能时,我似乎拥有更少的权限。谁能解释一下?

感谢您的回复;-)

一些附加信息:

  • 我的目标支持功能我使用 ping 命令和 CAP_NET_RAW 进行了检查
  • 内核 4.4.32-rt43
  • RFS:ext4
  • 我将帖子缩减为示例程序,我同意将 CAP_NET_RAW 添加到该程序是没有意义的。
  • 如果我添加 CAP_DAC_OVERRIDE 会起作用,但我想避免这种情况。

【问题讨论】:

    标签: c linux pthreads privileges linux-capabilities


    【解决方案1】:

    设置文件系统功能在许多方面就像使程序 SUID/SGID。在这种AT_SECURE == 1 执行模式下,内核限制了原始用户可以对进程执行的操作。潜在的侵入性操作,例如使用ptrace 附加进程或通过/proc 访问进程,被内核阻止,因此用户无法使用该程序来提升他们的权限。 (出于安全原因,glibc 和其他库也禁用了某些功能。)通常,这些限制仅适用于 不同 用户 ID 拥有的进程,但具有功能(和 SELinux 上下文),只是用户 ID 比较不再需要检测信任边界的交叉。

    在 glibc 中,与当前线程不同的线程的 pthread_setname_np 是通过写入 /proc/self/task/TID/comm 文件来实现的,因此它会遇到这些限制。内核可以想象为共享相同地址空间的任务的这种自我修改实现异常,但似乎没有实现,因此失败。而且我真的不能责怪内核人员,因为很难纠正这些问题,而不是引入任何漏洞。

    【讨论】:

    • 感谢弗洛里安的回答。我还假设 pthread_setname_np 尝试写入 /proc/PID/comm 如果它不是程序正在运行的线程。你有什么建议我的解决方案。直接写入 /proc/self/task/TID/comm.. 容易吗?所以写我自己的 pthread_setname 函数。
    • 所以在我的最终解决方案中,我将线程名称作为参数提供给在 pthread_create 中调用的函数,并在此函数中调用 pthread_setname_np 来设置名称。因为按照 Florian 的描述,只允许在自己的线程中设置名称。
    猜你喜欢
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    相关资源
    最近更新 更多