C中的setgid()调用不起作用

时间:2017-07-13 19:30:15

标签: c linux

我正试图放弃C程序中的权限,无论我做什么,GID仍为0.经过数小时的研究,我一无所知:(

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <grp.h>

int main(int argc, char *argv[]) {

        initgroups("nobody", 65534);
        setresuid(65534,65534,65534);
        setresgid(65534,65534,65534);
        setegid(65534);
        printf("gid: %d\n", getegid());
        execv("/usr/bin/id", argv);

}

返回:

gid: 0
uid=65534(nobody) gid=0(root) groups=65534(nogroup)

当我将所有三个(R,E和SGID)明确设置为65534时,为什么GID为0?

1 个答案:

答案 0 :(得分:2)

要设置GID值,进程需要有效的UID为0(root),但是在调用setresgid()之前,您的代码会通过将UID值设置为65534来小心地丢弃root权限,因此调用失败 - 如你所知,你已经测试了函数的返回值。

将来自setresuid()setresgid()的来电顺序颠倒过来(当然还要删除多余的setegid()和额外的printf())。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>  // Archaic: shouldn't be needed (but Linux docs list it)
#include <grp.h>

int main(int argc, char **argv)
{
    if (initgroups("nobody", 65534) == 0 &&
        setresgid(65534, 65534, 65534) == 0 &&
        setresuid(65534, 65534, 65534))
        execv("/usr/bin/id", argv);
    fprintf(stderr, "Oops!\n");
    return 0;
}

如果您愿意,可以在错误报告中更加小心。请记住,execv()如果成功则不会返回;没有必要测试它的返回值。