Pourquoi les utilisateurs privés doivent-ils définir setgid () pour des groupes supplémentaires

8

Les divers set*gid()appels système nécessitent des privilèges pour changer de groupe, sauf dans de très rares cas. La modification du groupe principal en l'un des groupes supplémentaires des processus ne semble pas être l'un d'eux, ce qui signifie que les commandes newgrp/, sgpar exemple, doivent élever les privilèges pour changer de groupe principal.

Y a-t-il une raison pour laquelle setgid()/ setegid()/ setregid()/ setfsgid()ne permet pas de passer à un groupe supplémentaire sans privilèges? Si oui, quelle en est la raison?

William Hay
la source
1
Pas sûr non plus. Notez que vous pouvez chgrp un fichier à l'un de vos groupes supplémentaires, donc si vous avez accès en écriture à une zone sans noexec, nosuid, vous pouvez contourner cette limitation (en créant une copie de /usr/bin/envavec l'autorisation setgid).
Stéphane Chazelas
La commande newwp newwp le fait déjà pour moi AFAICT mais générer un programme externe n'est pas toujours ce que l'on veut faire.
William Hay
Notez que cela newgrp/sgfait référence à la base de données des comptes et non à la liste de groupes supplémentaires du processus.
Stéphane Chazelas
Si votre gid ne figure pas également dans votre liste d'ID supplémentaires, alors l'autorisation setgid()vous permettrait de quitter l'appartenance à un groupe (ce qui serait un problème de sécurité), mais vous pouvez également le faire avec la même astuce exécutable setgid que ci-dessus, et votre gid est généralement également dans votre liste supplémentaire ( initgroups(3)prend un argument gid juste pour cela).
Stéphane Chazelas

Réponses:

3

Bien sûr, le casse-tête fondamental ici est que les vérifications des autorisations du système de fichiers sont basées sur la combinaison (de l'UID effectif et) du GID effectif et des GID supplémentaires. Ainsi, du point de vue des vérifications des autorisations de fichiers, le GID effectif est équivalent aux GID supplémentaires, ce qui conduit à la question du PO. (En passant: si nous parlons de Linux, ce sont en fait l'UID / GID du système de fichiers qui sont utilisés dans les vérifications des autorisations du système de fichiers, plutôt que l'UID et le GID effectifs, mais les anciens ID ont presque toujours les mêmes valeurs que les derniers ID. )

Ainsi, il doit y avoir des cas où les GID réels / effectifs / enregistrés ne sont pas équivalents aux GID supplémentaires. (Je regroupe les GID réels / effectifs / enregistrés ensemble, car les règles d'autorisation set * gid () normales indiquent qu'un processus non privilégié peut changer n'importe lequel de ces GID à la même valeur que l'un des deux autres.)

Et en effet, il y a quelques cas de ce genre. access (2) effectue ses vérifications en fonction de l' ID utilisateur réel et de l'ID de groupe du processus . Si un utilisateur non privilégié était en mesure de modifier l'ID de groupe réel pour qu'il soit le même que l'un des GID supplémentaires qui n'est pas le GID effectif ou enregistré, alors le comportement d'accès (2) pourrait être manipulé.

Il existe d'autres cas de ce genre. Voir la page de manuel Linux mkdir (2) , pour un exemple. Selon que le bit du mode set-GID est défini sur le répertoire parent, un nouveau fichier créé dans le répertoire prend la propriété de son groupe à partir du GID effectif du processus de création. Encore une fois, si un processus non privilégié pouvait changer son GID effectif pour être identique à l'un de ses GID supplémentaires, il pourrait manipuler la propriété de groupe de nouveaux fichiers de manière inattendue. Des commentaires similaires s'appliquent à mknod (2) et aux appels IPC System V semget (2), shmget (2) et msgget (2).

Il existe également des cas spécifiques à Linux où les GID d'ensemble réels / effectifs / enregistrés ne sont pas équivalents aux GID supplémentaires. Voir process_vm_readv (2) et prlimit (2), par exemple.

mtk
la source
Remarque: @mtk est l'auteur de l' interface de programmation Linux .
Stéphane Chazelas
Le gid effectif détermine la propriété du groupe des nouveaux fichiers. Mais vous pouvez ensuite changer ce groupe en l'une de vos gids supplémentaires par la suite (et également donner le bit setgid permettant à votre processus de faire efficacement un setgid ()). Cela semble donc un peu comme une faible raison.
Stéphane Chazelas
@ StéphaneChazelas: d'accord, c'est un peu faible. Sur OTOH, c'est maintenant un processus en deux étapes qui (et j'atteins ici) a le potentiel pour des courses étranges. Mais, à part ce cas, il y en a d'autres que je mentionne ci-dessus. Je ne connais pas la raison précise de cette décision de conception. C'était peut-être access (2), car c'est une partie ancienne de l'API. Beaucoup d'autres ne sont arrivés que plus tard (ou sont spécifiques à Linux) ou (je suppose) n'étaient pas présents sur BSD lorsque des GID supplémentaires ont été ajoutés. Ou, peut-être, il s'agissait simplement de préserver le comportement historique; Je vois que vous avez ajouté ce point comme réponse.
mtk
3

Je pense que la raison est avant tout historique. Les groupes supplémentaires n'ont pas été ajoutés avant 4.2BSD (vers 1983). Avant cela, vous n'aviez que les uids et les gids réels et efficaces.

Le comportement de setuid / setgid était complètement symétrique et n'avait aucune raison de ne pas l'être. Vous devez changer d'utilisateur avec suet regrouper avec sg/ newgrptous les exécutables setuid. Les informations sur l'appartenance à un groupe d'utilisateurs résidaient uniquement dans la base de données d'utilisateurs, pas dans les attributs des processus.

Et l'interface setuid / setgid n'a pas été modifiée lorsque des gids supplémentaires ont été ajoutés.

Techniquement maintenant, si vous avez accès en écriture à un système de fichiers (où l'exécution et setuid / setgid ne sont pas désactivés), vous pouvez toujours définir votre ID utilisateur effectif ou réel sur n'importe lequel de vos gids supplémentaires (sans avoir à recourir à sg/ newgrplequel uniquement btw permettent de passer aux groupes définis dans la base de données utilisateurs, ce qui n'est pas forcément la même que la liste des gids supplémentaires du processus).

cp /usr/bin/env .
chgrp any-sup-group env
chmod g+s ./env

Et lors de l'exécution env, votre egid passe à any-sup-group.

Stéphane Chazelas
la source