4

I have a git (actually git-annex) repository I'm trying to make shared, part of which involves setting the set-group-id bit on several directories. This is on a Debian GNU/Linux Stretch box, on an ext4 filesystem. For some odd reason, chmod g+s DIRECTORY is being ignored (blank lines around chmod block added for readability):

$ stat objects
  File: objects
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd06h/64774d    Inode: 12353692    Links: 260
Access: (0775/drwxrwxr-x)  Uid: ( 1000/ anthony)   Gid: ( 1025/git-books)
Access: 2018-07-30 14:43:13.831641743 -0400
Modify: 2018-07-28 14:28:14.970667931 -0400
Change: 2018-07-30 14:46:38.179597449 -0400
 Birth: -

$ chmod g+s objects
$ echo $?
0

$ stat objects
  File: objects
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd06h/64774d    Inode: 12353692    Links: 260
Access: (0775/drwxrwxr-x)  Uid: ( 1000/ anthony)   Gid: ( 1025/git-books)
Access: 2018-07-30 14:43:13.831641743 -0400
Modify: 2018-07-28 14:28:14.970667931 -0400
Change: 2018-07-30 14:50:43.355539381 -0400
 Birth: -

What I've checked so far:

  • There do not appear to be any weird mount options (e.g., nosuid) that might block it from working. I checked both fstab and /proc/mounts, which shows /dev/mapper/slow-srv /srv ext4 rw,relatime,nobarrier,errors=remount-ro,stripe=384,data=ordered 0 0
  • There does not appear to be any weird ACL on the directory; to be sure I did setfacl -b objects. Even after doing so, chmod continued to not work.
  • strace on chmod shows the syscall succeeding, and has the sgid bit set:
    fchmodat(AT_FDCWD, "annex", 02775) = 0
  • Other directories on the same filesystem have the set-group-id bit set. In fact, I set some earlier in the same session, in a different git-annex repository.
derobert
  • 107,579
  • 20
  • 231
  • 279

1 Answers1

4

It turns out that although I had created that group and added myself to it several days ago, and this was what I thought was a new ssh connection, it wasn't really. Due to using OpenSSH's connection multiplexing feature (ControlMaster/ControlPath/etc.), I was actually logging in on a connection that was ~10 days old, so my session (processes) didn't have the new group set. I confirmed this with id.

After logging in via ssh -o ControlPath=none HOST, id confirms my session has the git-books group, and the chmod g+s works.

As to why that didn't give a permission denied error, it seems the standard requires this behavior for files and permits implementations to ignore the bits:

If the calling process does not have appropriate privileges, and if the group ID of the file does not match the effective group ID or one of the supplementary group IDs and if the file is a regular file, bit S_ISGID (set-group-ID on execution) in the file's mode shall be cleared upon successful return from chmod().

Additional implementation-defined restrictions may cause the S_ISUID and S_ISGID bits in mode to be ignored.

Single Unix Spec v4 2018 edition, chmod. http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html (registration may be required).

Probably, returning an error would merely be sane, not conformant ☹.

derobert
  • 107,579
  • 20
  • 231
  • 279