即使我不是超级用户,如何为 Nice() 提供负值并运行而不会出现错误,我可以吗
system("su");
nice(-1);
它要求输入我不想要的密码?
答案1
如果您拨打电话su
,系统将要求您输入密码,除非您是 root 用户。
为了能够重新处理负值,该过程需要:
- 成为根
- 或者具有 CAP_SYS_NICE 能力(参见在 gnu/linux 上设置文件权限等有哪些不同方法和http://man7.org/linux/man-pages/man7/capability.7.html)
答案2
你不能。这就是系统的重点。普通用户不得提高其任务的优先级。
答案3
进程无法提升自己的权限。
进程绝对没有办法提升其权限。如果可以的话它就已经拥有它们了。
如果一个进程有真实的或保存的uid提升,那么它可以将该uid复制到有效uid中;如果它具有允许的功能,那么它可以将这些功能复制到有效集中,但它必须首先具有这些权限。你不能凭空对它们施魔法(一把可以随意创造一把钥匙的锁有什么用)。
那么如何在 Unix(包括 Gnu/Linux)中提升权限呢?
(请小心,仅适用于专家)
有两种方法(传统的一种,但它们都很相似,而且原来的方法可能有一天会消失)。对于这两种情况,当您调用 exec 时都会发生这种情况。 (好吧,我在上面撒了谎,因为运行 exec 后我们处于同一进程中,权限已更改,但正在运行新代码)。
- 设置可执行文件的 setuid 和/或 setuid 位:当文件被
exec
编辑时,用户 ID 和/或组 ID 将更改为文件的用户 ID 和/或组 ID(可能是 root)(这不适用于大多数 Unix 上的脚本语言) )。 - 设置可执行文件的功能位:当文件被
exec
编辑时,进程将获得文件中设置的功能。这就是现在的推荐方法。- 如果您要将 seduid 根程序转换为功能,则可以根据需要设置允许的功能,并设置有效位(这会将所有允许的功能复制为有效)。
- 当您编写新程序时,它可以感知功能,因此最好不要设置有效位,您的程序可以根据需要复制和清除有效功能(这可以减少错误(包括漏洞利用)的影响)。
例子:
//renice.cc
#include <unistd.h>
#include <sys/capability.h>
class Renice {
cap_t original_cap_state;
cap_t can_nice_cap_state;
cap_value_t cap_list[1];
public:
Renice() {
original_cap_state = cap_get_proc();
if ( original_cap_state == NULL)
/* handle error */;
can_nice_cap_state = cap_get_proc();
if ( can_nice_cap_state == NULL)
/* handle error */;
cap_list[0] = CAP_SYS_NICE;
if (cap_set_flag(can_nice_cap_state, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1)
/* handle error */;
}
~Renice() {
if (cap_free(original_cap_state) == -1 )
/* handle error */;
}
void new_value(int v) {
if (cap_set_proc(can_nice_cap_state) == -1)
/* handle error */;
nice (v);
/* handle error */
if (cap_set_proc(original_cap_state) == -1)
/* handle error */;
}
};
int main () {
Renice renice;
renice.new_value(-1);
nice (-2); //won't work, capability no longer set
sleep (30);
}
- 编译:
g++ -lcap renice.cc
- 设置功能:
sudo setcap CAP_SYS_NICE+p a.out
- 运行:
./a.out