ptrace - 为什么在setuid之后ptrace不附加到进程?

标签 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进程和top运行。问题是即使删除了特权,我也无法从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上尝试了相同的结果。

所以我的问题是:


为什么ptrace无法附加到具有与gdb相同的有效UID的进程?
是否可以某种方式放弃程序的特权,以便可以从无特权的gdb附加到它?怎么样?


谢谢。

最佳答案

我自己找到了解决方案。

内核中的每个进程都有一个“ dumpable”标志。当进程执行setuid或setgid时(至少在我来说,当进程放弃特权时),此标志将被清除,普通用户无法使用调试器附加到该进程,并且该进程崩溃也不会产生崩溃转储。出于安全考虑,这样做是为了保护进程内存中以提升的特权获得的任何敏感数据。

为了解决该问题,该过程可以通过将“ dumpable”标志设置为1来明确允许调试。

prctl(PR_SET_DUMPABLE, 1);


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

关于ptrace - 为什么在setuid之后ptrace不附加到进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21337923/

相关文章:

C - 获取用 popen 打开的进程的 PID

c++ - ptrace如何捕捉fork的系统调用?

perl - 如何使用 Perl 的 Archive::Tar 保留 tar 存档中的 setuid 位?

c - 如何从 root 使用 setuid() 成为用户,以后有可能再次成为 root?

perl - 当用作 cgi-bin 时,如何使用 setuid() 成功运行 Perl 脚本?

c - 修改 strace 以捕获并替换打开的系统调用中的文件名

linux - gdb 无法附加到进程

linux - 通过一条汇编指令单步执行一个过程

c - 需要帮助改进一个小型 C 程序

c - 以 root 身份执行命令,无需 root 密码或 sudo