Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

getgroups(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)115 / 80 / 158 / 80
Since (kernel)1.0
Man pageman2/getgroups.2 (cached roff, dated 2021-03-22; setgroups documented on the same page); man2/setgroups.2 is a one-line .so alias to getgroups.2
glibc wrappergetgroups(3) (@@GLIBC_2.2.5) declared in unistd.h; setgroups(3) (@@GLIBC_2.2.5) declared in grp.h under _DEFAULT_SOURCE (since glibc 2.19) or _BSD_SOURCE before that (getgroups.2, SYNOPSIS); both handle the 16/32-bit kernel split
Aliases coveredsetgroups (116 / 81 / 159 / 81, SC-setgroups); getgroups32 (i386 205, SC-getgroups32); setgroups32 (i386 206, SC-setgroups32)
Ledger IDSC-getgroups

Purpose

getgroups() returns the calling process’s supplementary group IDs; setgroups() replaces them. Supplementary groups are the third group credential besides real and effective GID: the kernel checks all of them against a file’s group bits.

Synopsis

#include <unistd.h>
int getgroups(int size, gid_t list[]);
#include <grp.h>
int setgroups(size_t size, const gid_t *list);

Arguments and behavior

getgroups(size, list): size is the capacity of list; if the process belongs to more than size supplementary groups the call fails. It is unspecified whether the effective GID appears in the returned list, so an application should consult getegid(2) as well (getgroups.2, DESCRIPTION). With size 0, list is not touched and the number of supplementary groups is returned – the usual sizing idiom. setgroups(size, list) replaces the whole set; setgroups(0, NULL) drops all supplementary groups. A process may hold up to NGROUPS_MAX supplementary IDs besides the effective GID; the man page records 32 before Linux 2.6.4 and 65536 since, and the kernel UAPI header on this host agrees (/usr/include/linux/limits.h: 65536; glibc’s bits/posix1_lim.h still carries a fallback NGROUPS_MAX 8). Since 2.6.4 the maximum is also exposed read-only at /proc/sys/kernel/ngroups_max (getgroups.2, NOTES). The 16-bit originals gained getgroups32()/setgroups32() in Linux 2.4.

Return value and errors

getgroups() returns the number of supplementary group IDs, setgroups() returns 0; on error -1 with errno (getgroups.2, RETURN VALUE). Errors: EFAULT, invalid list address; EINVAL (getgroups), size smaller than the number of groups but not zero; EINVAL (setgroups), size exceeds NGROUPS_MAX; ENOMEM (setgroups); EPERM (setgroups), caller lacks CAP_SETGID in its user namespace, or since Linux 3.19 setgroups() is denied in this user namespace via /proc/[pid]/setgroups (getgroups.2, ERRORS).

Flags and constants

NGROUPS_MAX: 65536 (/usr/include/linux/limits.h); CAP_SETGID is 6 (/usr/include/linux/capability.h).

Security and notes

The set is inherited from the parent and preserved across execve(2) (getgroups.2, NOTES). At the kernel level the IDs are per-thread; NPTL wrappers broadcast changes to all threads (getgroups.2, C library/kernel differences). setgroups() requires privilege and is therefore not covered by POSIX.1 (CONFORMING TO). The companion library function initgroups(3) (cached man3/initgroups.3) populates the supplementary list from the user database. Cross-reference: getgid, setreuid, execve.

References

  • https://man7.org/linux/man-pages/man2/getgroups.2.html
  • /usr/include/linux/limits.h (NGROUPS_MAX 65536)
  • /usr/include/x86_64-linux-gnu/bits/posix1_lim.h (NGROUPS_MAX 8 fallback)
  • /usr/include/linux/capability.h (CAP_SETGID value 6)
  • man3/initgroups.3 (cached)