这实际上是一个三部分的问题,我将在下面解释,但问题是:
我有一个运行在Linux (多个发行版)上的C程序,通常由具有正常权限的用户运行,但是程序的某些部分必须以根权限运行。为此,我使用了set-UID标志,就其本身而言,它工作得很好。
但是,现在我想用正常的用户权限来调试程序,并且我发现我有一个CATC-22。我刚刚添加了一个函数来创建一个临时文件(/tmp/my_name-XXXXXX),该函数是从程序中的许多点调用的。无论出于什么原因,该函数在运行时发出以下消息:
sh: /tmp/my_name-hhnNuM: Permission denied(当然,实际名称各不相同。)然而,该程序能够执行原始的套接字函数,我绝对知道除了root之外,用户不能执行这个函数。(如果我移除setuid标志,程序将不幸地失败。)
如果我在没有sudo的情况下通过gdb运行这个程序,它就会死在原始的套接字上(因为gdb显然没有--或者可能不能--遵守程序上的setuid标志)。如果我在"sudo gdb“下运行它,那么一切都很好。如果我以"sudo ./my_name“的形式运行它,那么一切都正常。
下面是该程序的ls -l输出:
-rwsr-xr-x 1 root root 48222 Jun 23 08:14 my_name所以我的问题,没有特别的顺序:
发布于 2012-06-23 15:53:49
1在gdb下正确调试setuid应用程序的唯一方法是以根用户身份运行gdb。对于setuid应用程序来说,最明智的方法是在应用程序启动后附加到它。要做到这一点,一个快速的技巧是在setuid应用程序中添加一行:
kill(getpid(), SIGSTOP);这将导致它在此时停止,然后使用以下方法附加gdb:
sudo gdb <application> <pid>然后,您将被附加到应用程序,并可以正常地调试它。
2 sudo更改规则,因为它允许将当前用户环境中的各种项导出到根用户环境中。这完全依赖于当前的sudo配置,并且可能会给您留下一个与setuid应用程序非常不同的环境,这就是为什么您需要依赖一些技巧,比如停止应用程序,然后在运行时附加到它。
此外,应用程序中可能有逻辑来检测它是否在setuid环境中运行--在sudo下运行时,实际情况并非如此--记住sudo将进程的所有id字段(实uid、有效uid和已保存的uid)设置为相同的值,而setuid没有(真正的uid仍然是原始调用方的id)。可以使用getresuid()调用来确定这三个变量的状态。
3的问题是,Permission Denied消息的前缀是sh:;这似乎意味着正在执行另一个子进程,试图访问该文件。调用mkstemp之后,您可能需要放宽读取文件的权限,以便子进程能够读取该文件。
https://stackoverflow.com/questions/11169656
复制相似问题