我在 Linux 机器上有一些 C++ 代码,其目的是作为任意用户运行一些代码。
#include <sys/capability.h>
#include <unistd.h>
void doAsUser(uid_t uid) {
if (CAP_IS_SUPPORTED(CAP_SETUID)) {
cout << "Do we have CAP_SETUID? " << cap_get_bound(CAP_SETUID) << endl;
} else {
cout << "CAP_SETUID not supported!" << endl;
}
uid_t ruid, euid, suid;
getresuid(&ruid, &euid, &suid);
cout << "UIDs: " << ruid << " " << euid << " " << suid << endl;
// assume credentials of user
status = seteuid(uid);
if (status < 0) {
cerr << "FATAL ERROR: Couldn't set uid: " << strerror(errno) << endl;
exit(1);
}
// do stuff here...
// re-assume credentials of program
status = seteuid(my_uid);
if (status < 0) {
cerr << "FATAL ERROR: Couldn't reset uid: " << strerror(errno) << endl;
exit(1);
}
}
但是,运行此函数时,您一定会得到以下输出:
$ sudo ./program
...
Do we have CAP_SETUID? 1
UIDs: 0 0 0
FATAL ERROR: Couldn't set uid: Operation not permitted
这里发生了什么?我认为以 root 身份运行的东西(你知道,UID 0 和 CAP_SETUID)可以假定任何其他用户的有效 UID。
编辑:这个问题没有充分回答我的问题,因为,正如它所说,“为了执行调用,seteuid
即使当时的 EUID 不为 0,SUID 也必须为 0”。我的 SUID 是 0,我的 CAP_SETUID 是 1,并且我没有其他安全框架。