在execvp之前设置gid,但是id命令显示多个组

时间:2017-08-01 11:52:13

标签: c linux

我有一个项目,我想使用root来作为普通用户执行程序。

首先我有一个正常的用户fgo whoes uid和gid是501.

id fgo
[root@cpera test]# id fgo
uid=501(fgo) gid=501(fgo) groups=501(fgo)

这是示例代码

#define _GNU_SOURCE
#include <sched.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/capability.h>
#include <sys/resource.h>
#include <unistd.h> 
#include<stdlib.h>
#include <stdio.h>
#include <string.h>
int main( int argc,char *argv[]){ 
    while(setgid(501)!=0) sleep(1);
    while(setuid(501)!=0) sleep(1);
    printf("start to exec\n");
    execvp("/bin/sh",NULL);
}

编译并执行

gcc a.c && ./a.out

输出是:

[root@cpera test]# ./a.out 
start to exec
[fgo@cpera test]$ id
uid=501(fgo) gid=501(fgo) groups=501(fgo),0(root)

我用谷歌搜索它,发现来自id的组被称为supplementary group从父进程继承。GID, current, primary, supplementary, effective and real group IDs?

如何才能使root不在子进程的组中?

1 个答案:

答案 0 :(得分:1)

使用setgroups()重置补充组:

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

int main (int argc, char *argv[])
{ 
    if (setgroups (0, NULL) != 0) {
        perror ("setgroups");
        exit (1);
    }

    if (setgid (501) != 0) {
        perror ("setgid");
        exit (1);
    }

    if (setuid (501) != 0) {
        perror ("setuid");
        exit (1);
    }

    printf ("start to exec\n");

    if (execl ("/bin/sh", NULL) != 0) {
        perror ("execl");
    }

    return 1;
}