chmod 2775 sets the mode to rwxrwsr-x: the permissions of 775 plus the setgid bit, the leading 2. On a directory, new files and subdirectories created inside get the directory’s group instead of the creator’s primary group, and new subdirectories get the setgid bit too, so a whole tree stays in one group. The s in the group’s execute slot shows setgid and group execute together.
A shared project directory
sudo groupadd devs
sudo usermod -aG devs alice # takes effect at alice's next login
sudo chgrp -R devs /srv/project
sudo find /srv/project -type d -exec chmod 2775 {} +
sudo find /srv/project -type f -exec chmod 664 {} +
ls -ld /srv/project # drwxrwsr-x 2 root devs 4096 Oct 15 09:00 /srv/project
Without setgid, a file alice creates belongs to her own group, and Bob in devs can’t edit it. With it, the file is in devs from the start.
What setgid doesn’t do
- It sets the group, not the mode. A new file still gets its creator’s umask, so under
022it’s644and the group can’t write it. Give the team umask002, or put a default ACL on the directory, which takes the umask’s place there:setfacl -d -m g::rwX /srv/project. - It doesn’t touch existing files. It applies only when an entry is created.
cpwithout-por-acreates a new file, which takes the directory’s group;mvwithin one filesystem is a rename and keeps the old group. Runchgrp -Rafter moving things in. - GNU chmod won’t clear it with a numeric mode.
chmod 775on a2775directory leaves2775. Usechmod g-s dir, or GNU’s five-digitchmod 00775 dir.
Group write is shared power
Every member of devs can delete or rename any file in the directory, not only their own. To limit deletion to each file’s owner, add the sticky bit: chmod 3775 gives rwxrwsr-t. Keep 2775 off home directories, too: sshd’s StrictModes rejects key logins when the home directory is group-writable.
On a program
On an executable file, setgid runs it with the file’s group as its effective group ID: 2755 is rwxr-sr-x. The same limits as setuid apply: Linux ignores it on #! scripts, and nosuid mounts disable it.
On other systems and in containers
- BSD and macOS always give a new file its directory’s group, so the bit isn’t needed there for directories.
- Kubernetes:
securityContext.fsGroupdoes this to a pod’s volumes for you, on volume types that support it: the volume is group-owned by that GID, its directories get setgid, and the group gets read and write. - Git:
git init --bare --shared=groupcreates a repository with setgid directories and group-writable files, so pushes from different users keep working. Git itself stores neither directory modes nor setgid.