[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#698102: eglibc: initgroups changes egid on kfreebsd



I've reworked the test program as follows:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    #define NGROUPS 32

    void call() {
            gid_t groups[NGROUPS];


            int ngroups = getgroups(NGROUPS, groups), i;
            printf("gid = %d egid = %d  groups =", (int) getgid(), (int) getegid());
            for(i =0; i< ngroups; i++) printf(" %d", (int) groups[i]);
            printf("\n");
    }

    int main(void) {
            gid_t groups[] = {1, 2};
            call();
            setgroups(2, groups);
            call();
            setgid(groups[0]);
            call();
            setuid(groups[0]);
            call();
    }

now the dependence on glibc initgroups() is removed.

On FreeBSD and kFreeBSD, the first group passed to setgroups becomes the
effective group ID.  On Linux, it does not:

    kfreebsd# gcc test.c && ./a.out
    gid = 0 egid = 0  groups = 0
    gid = 0 egid = 1  groups = 1 2
    gid = 1 egid = 1  groups = 1 2
    gid = 1 egid = 1  groups = 1 2

    freebsd9chroot# gcc test.c && ./a.out
    gid = 0 egid = 0  groups = 0
    gid = 0 egid = 1  groups = 1 2
    gid = 1 egid = 1  groups = 1 2
    gid = 1 egid = 1  groups = 1 2

    linux# gcc test.c sudo ./a.out
    gid = 0 egid = 0  groups = 0
    gid = 0 egid = 0  groups = 1 2
    gid = 1 egid = 1  groups = 1 2
    gid = 1 egid = 1  groups = 1 2

The original program in freebsd9chroot (modified to use a different
username):
    # ./a.out
    pw_name=jepler
    pw_uid=1001
    pw_gid=1001
    uid=0(root) gid=0(wheel) groups=0(wheel)
    uid=0(root) gid=0(wheel) egid=1001(jepler) groups=1001(jepler),5(operator)
    uid=0(root) gid=0(wheel) egid=1001(jepler) groups=1001(jepler),5(operator)
    uid=1001(jepler) gid=1001(jepler) groups=1001(jepler),5(operator)

Unfortuantely, POSIX declined to specify setgroups() and initgroups() is
not in any standard, so it's hard to say which behavior is right and
which is wrong.  It seems possible to argue any of the following:
        
 1. The bug is in kFreeBSD's implementation of setgroups(), which must
    be fixed so that eglibc's initgroups() implementation works as
    expected.

 2. The bug is in eglibc's implementation of initgroups(), which must be
    fixed so that it works properly with kFreeBSD's setgroups().

 3. Since both behaviors of setgroups() and initgroups() are seen "in
    the wild", programs that depend on the linux kernel behavior are
    broken and should be fixed as they become known.

Personally I'm leaning towards 3 here, since these are buggy not only on
debian/kFreeBSD but on real FreeBSD as well.

Jeff


Reply to: