我的Linux守护程序有问题.它以root权限开始,进行一些配置,然后通过切换到某个用户和组来永久删除权限并继续工作.切换到非特权用户的方式如下:
void switch_to_user_group(std::string const& username, std::string const& groupname)
{
// Switch to user/group
gid_t gid = getgid();
if (!groupname.empty())
{
gid = get_group_id(groupname);
if (0 != setgid(gid))
{
std::cout << "Failed to switch to group " << gid << std::endl;
std::abort();
}
}
if (!username.empty())
{
uid_t uid = get_user_id(username);
if (initgroups(username.c_str(), gid) != 0)
{
std::cout << "initgroups failed" << std::endl;
std::abort();
}
if (0 != setuid(uid))
{
std::cout << "Failed to switch to user " << uid << std::endl;
std::abort();
}
}
}
Run Code Online (Sandbox Code Playgroud)
交换机正常运行,我可以看到ps和顶部运行在我的用户下的进程.问题是我无法从gdb附加到此进程,即使它已经删除了权限.输出是:
Attaching to process 15716
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
Run Code Online (Sandbox Code Playgroud)
我正在流程切换到的同一个用户下运行gdb,并且我能够连接到最初在该用户下启动的其他进程.我在Kubuntu 13.10(YAMA已禁用),Debian 6和7上尝试了相同的结果.
所以我的问题是:
谢谢.
我自己找到了解决方案.
每个进程在内核中都有一个"dumpable"标志.当进程执行setuid或setgid时(至少在我的情况下,当进程丢弃权限时)此标志被清除,普通用户无法使用调试器附加到此进程,并且进程崩溃也不会产生崩溃转储.出于安全原因,这样做是为了保护使用可能在进程内存中的提升权限获得的任何敏感数据.
要解决该问题,该进程可以通过将'dumpable'标志设置为1来明确允许调试.
prctl(PR_SET_DUMPABLE, 1);
Run Code Online (Sandbox Code Playgroud)
这必须在setgid/setuid调用之后完成.