Processus qui désescaladent les privilèges via setuid()
et setgid()
ne semblent pas hériter des appartenances aux groupes de l'uid / gid qu'ils ont définis.
J'ai un processus serveur qui doit être exécuté en tant que root pour ouvrir un port privilégié; après cela, il désescalade en un uid / gid spécifique non privilégié, 1 - par exemple, celui de l'utilisateur foo
(UID 73). L'utilisateur foo
est membre du groupe bar
:
> cat /etc/group | grep bar
bar:x:54:foo
Donc, si je me connecte en tant que foo
, je peux lire un fichier /test.txt
avec ces caractéristiques:
> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar 8 16:22 /test.txt
Cependant, le programme C suivant (compilation std=gnu99
), lors de l'exécution root:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main (void) {
setgid(73);
setuid(73);
int fd = open("/test.txt", O_RDONLY);
fprintf(stderr,"%d\n", fd);
return 0;
}
Signale toujours l' autorisation refusée . J'imagine que cela a à voir avec le fait qu'il ne s'agit pas d'un processus de connexion, mais cela gêne en quelque sorte la façon dont les autorisations sont censées fonctionner.
1. Ce qui est souvent SOP pour les serveurs, et je pense qu'il doit y avoir un moyen de contourner cela car j'ai trouvé un rapport de quelqu'un le faisant avec apache - apache a été ajouté au groupe audio et peut apparemment utiliser le système audio. Bien sûr, cela se produit probablement dans un fork et non dans le processus d'origine, mais en fait, le cas est le même dans mon contexte (c'est un processus enfant forké après l'appel de setuid).
la source
setuid()
/setgid()
appels autour.setgid(54)
au lieu desetgid(73)
(comme dans/etc/groups
, le groupebar
a gid 54), cela fonctionne-t-il?setuid()
recommencer après l'avoir fait ... mais, hmmm ... je pense que vous pouvez avecseteuid()
...Réponses:
Le problème est que ,
setuid
etsetgid
ne suffisent pas à donner votre processus tous les pouvoirs dont il a besoin. Les autorisations d'un processus dépendent deVoir
man 7 credentials
pour obtenir un aperçu plus détaillé. Ainsi, dans votre cas, le problème est que vous définissez correctement l'UID et le GID, mais vous ne définissez pas les groupes supplémentaires du processus. Et le groupebar
a GID 54, no 73, il n'est donc pas reconnu comme un groupe dans lequel se trouve votre processus.Tu devrais faire
la source
dialout
groupe et cela a fonctionné la première fois.OK, j'ai fait un peu le tour du filet. J'ai d'abord pensé que l' APUE détiendrait toutes les réponses, mais je me suis trompé. Et ma copie (ancienne édition) est à l'œuvre, donc ... Le chapitre 5 du Manuel d'administration Unix et Linux semble prometteur, mais je ne l'ai pas (juste une copie des deux premières éditions, également à l'œuvre).
Les petites ressources que j'ai trouvées (google pour "daemon writing unix") parlent toutes d'étapes importantes, comme comment se dissocier du tty, etc. Mais rien sur l'UID / GID. Étrangement, même la vaste collection HOWTO sur http://tldp.org ne semble pas avoir de détails. Seul excetion est Jason court Let Ecrivez un Daemon Linux - partie I . Chen, Wagner et Dean SUID ont démystifié tous les détails sur la façon dont SUID / SGID et tout ce désordre fonctionnent (un article dans USENIX 2002). Mais attention, Linux a un UID supplémentaire, le FSUID (voir les notes d'incompatibilité Unix de Wolter : Fonctions de réglage UID pour une discussion).
Démoniser un processus n'est certainement pas pour les âmes sensibles. Des considérations générales sur la sécurité sont données dans le guide de programmation sécurisé de D. Wheeler pour Linux et Unix - Création de logiciels sécurisés . Systemd promet de simplifier la plupart de cela (et donc de réduire la place pour les erreurs qui conduisent à des problèmes de sécurité), voir le manuel du démon .
la source
setuid()
, ce qui permet au processus de changer arbitrairement son UID. SUID est généralement destiné à permettre une escalade des autorisations (non privilégiées -> privilégiées), alorssetuid()
qu'il ne peut faire que le contraire.