为什么ptrace在setuid之后没有附加到进程?

时间:2014-01-24 16:43:29

标签: ptrace setuid

我的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();
        }
    }
}

交换机正常运行,我可以看到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.

我在流程切换到的同一个用户下运行gdb,并且我能够附加到最初在该用户下启动的其他进程。我在Kubuntu 13.10(YAMA已禁用),Debian 6和7上尝试了相同的结果。

所以我的问题是:

  1. 为什么ptrace无法附加到与gdb具有相同有效和真实UID的进程?
  2. 是否有可能以某种方式删除我的程序的权限,以便我可以从非特权的gdb附加到它?怎么样?
  3. 感谢。

1 个答案:

答案 0 :(得分:8)

我自己找到了解决方案。

有一个&#39; dumpable&#39;每个进程都在内核中标记。当进程执行setuid或setgid时(至少在我的情况下,当进程删除权限时)此标志被清除,普通用户无法使用调试器附加到此进程,并且进程崩溃也不会产生崩溃转储。出于安全原因,这样做是为了保护使用可能位于进程内存中的提升权限获得的任何敏感数据。

要解决此问题,该流程可以通过设置&#39; dumpable&#39;来明确允许调试。标志为1。

prctl(PR_SET_DUMPABLE, 1);

这必须在setgid / setuid调用之后完成。