only for the paranoid---getgroups(3) testcase



Here's a little testcase that can be used for confidence tests and for portability tests.

You can define FIRST_GETGROUPS_FAILS and/or SECOND_GETGROUPS_FAILS and see what's the result.

In addition to the code used in utilunix.c, there's a check that the result of the second call to getgroups() is not greater than the result of the first call.

There is no check whether the getgroups() function produces a buffer overflow. This is left as an excercise to the reader.

Roland
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <unistd.h>

#ifdef FIRST_GETGROUPS_FAILS
#define first_getgroups(a,b) (-1)
#else
#define first_getgroups(a,b) getgroups((a), (b))
#endif

#ifdef SECOND_GETGROUPS_FAILS
#define second_getgroups(a,b) (-1)
#else
#define second_getgroups(a,b) getgroups((a), (b))
#endif

int main(void)
{
	uid_t uid;
	gid_t *groups;
	int i, ngroups, n2groups;

	uid = geteuid();
	ngroups = first_getgroups(0, NULL);
	if (ngroups == -1)
		ngroups = 0;

	groups = calloc(ngroups + 1, sizeof(gid_t));
	assert(groups != NULL);

	if (ngroups != 0) {
		n2groups = second_getgroups(ngroups, groups);
		if (n2groups == -1)
			n2groups = 0;
		assert(n2groups <= ngroups);
		ngroups = n2groups;
	}

	groups[ngroups++] = getegid();

	for (i = 0; i < ngroups; i++) {
		(void)printf("%lu\n", (unsigned long int) groups[i]);
	}
	fflush(stdout);
	return (ferror(stdout));
}


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