2

我从 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:分机4
  • 我将帖子简化为示例程序,我同意将 CAP_NET_RAW 添加到该程序是没有意义的。
  • 如果我添加 CAP_DAC_OVERRIDE 它会起作用,但我想避免这种情况。
4

1 回答 1

2

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

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

于 2017-08-02T17:37:42.223 回答