Effectivement. Mon appel-système est nommé xchroot(2), et il diffère très fortement du chroot() POSIX qu'implémente Linux, que je ne compte d'ailleurs pas implémenter. Les différences sont:
xchroot(2) implique chdir(2);
xchroot(2) a pour effet de bord de fermer la totalité des descripteurs de fichiers référençant un répertoire de l'appelant, à l'exception de ceux dont il peut prouver qu'ils lui sont accessibles (parce qu'ils référencent des entrées dans son /...);
chdir("..") n'est pas toujours honoré; en fait, cet appel-système n'est honoré que si le répertoire ".." est lui aussi accessible depuis la racine du chroot;
il y a des restrictions importantes au droit de passer un descripteur de fichier référençant un répertoire dans les données ancillaires d'une socket UNIX.
De la sorte, même avec les privilèges maximaux, il est impossible de s'échapper d'un xchroot (Je vais peut-être les appeler comme ça, ce sera plus clair). Bien sûr avec des privilèges maximaux, on peut contourner le problème en remontant le disque dur ailleurs, mais sans cela, le xchroot est vraiment une prison complète.
Grâce à cela, xchroot(2) a pu être rendu non-privilégié, ce qui signifie que n'importe qui peut en créer un nouveau. C'est parfaitement inoffensif : on ne peut pas utiliser cette propriété pour s'en échapper, juste pour réduire la taille de son propre xchroot.
Autre particularité, le flag XCHROOT_USE_ROOTLINK de cet appel. Lorsqu'un processus l'emploie, si le binaire qu'il exécute actuellement comporte un lien racine (une sorte de lien matériel asymétrique pointant d'un fichier régulier vers un répertoire), alors le noyau donne à l'appelant pour nouvelle racine le répertoire visé. Cela signifie que les programmes peuvent s'appeler les uns les autres sans avoir accès au contenu des chroots de leurs descendants; tout au plus peuvent-ils partager les fichiers qu'ils désirent par /... .
Lorsque la pile réseau sera remise en place, elle fera usage des fichiers de périphérique de /dev pour déterminer les droits d'accès au réseau. De la sorte, xchroot(2) continuera bien à isoler les diverses ressources.
Je vais en revenir à ce document de RedHat référencé par patrick_g. L'une des grandes différences, c'est que le chroot() Linux ne fournit pas les fonctionnalités requises pour isoler toutes les applications. Dans le texte, RedHat envisage le cas où un utilisateur ou un démon sont placés dans un chroot, pas une simple application. Parce que, sous Linux, ça n'a pas de sens : si on chroote vim, comment pourrait-il accéder au fichier qu'il doit éditer?
Mais, avec xchroot(2) qui manipule la partition /... , ça devient possible, et chez moi, c'est au niveau de chaque application que les xchroots sont utilisés. Et là, aucun usage des permissions UNIX ne permet d'obtenir ce résultat.
(Pour ceux qui ne comprennent pas : /... est une partition spéciale, dépourvue de toute réalité sur le disque dur (comme /proc), et dont le contenu varie selon le processus qui l'observe; chaque processus ayant la faculté d'associer les fichiers de son choix aux noms qu'il souhaite dans /... . Pour une illustration de son utilisation, voyez mon post un peu au dessus de celui-ci.)
[^] # Re: Intéressant
Posté par Emmanuel Colbus . En réponse au journal Annonce : Manux 0.0.1. Évalué à 8.
Effectivement. Mon appel-système est nommé xchroot(2), et il diffère très fortement du chroot() POSIX qu'implémente Linux, que je ne compte d'ailleurs pas implémenter. Les différences sont:
De la sorte, même avec les privilèges maximaux, il est impossible de s'échapper d'un xchroot (Je vais peut-être les appeler comme ça, ce sera plus clair). Bien sûr avec des privilèges maximaux, on peut contourner le problème en remontant le disque dur ailleurs, mais sans cela, le xchroot est vraiment une prison complète.
Grâce à cela, xchroot(2) a pu être rendu non-privilégié, ce qui signifie que n'importe qui peut en créer un nouveau. C'est parfaitement inoffensif : on ne peut pas utiliser cette propriété pour s'en échapper, juste pour réduire la taille de son propre xchroot.
Autre particularité, le flag XCHROOT_USE_ROOTLINK de cet appel. Lorsqu'un processus l'emploie, si le binaire qu'il exécute actuellement comporte un lien racine (une sorte de lien matériel asymétrique pointant d'un fichier régulier vers un répertoire), alors le noyau donne à l'appelant pour nouvelle racine le répertoire visé. Cela signifie que les programmes peuvent s'appeler les uns les autres sans avoir accès au contenu des chroots de leurs descendants; tout au plus peuvent-ils partager les fichiers qu'ils désirent par /... .
Lorsque la pile réseau sera remise en place, elle fera usage des fichiers de périphérique de /dev pour déterminer les droits d'accès au réseau. De la sorte, xchroot(2) continuera bien à isoler les diverses ressources.
Je vais en revenir à ce document de RedHat référencé par patrick_g. L'une des grandes différences, c'est que le chroot() Linux ne fournit pas les fonctionnalités requises pour isoler toutes les applications. Dans le texte, RedHat envisage le cas où un utilisateur ou un démon sont placés dans un chroot, pas une simple application. Parce que, sous Linux, ça n'a pas de sens : si on chroote vim, comment pourrait-il accéder au fichier qu'il doit éditer?
Mais, avec xchroot(2) qui manipule la partition /... , ça devient possible, et chez moi, c'est au niveau de chaque application que les xchroots sont utilisés. Et là, aucun usage des permissions UNIX ne permet d'obtenir ce résultat.
(Pour ceux qui ne comprennent pas : /... est une partition spéciale, dépourvue de toute réalité sur le disque dur (comme /proc), et dont le contenu varie selon le processus qui l'observe; chaque processus ayant la faculté d'associer les fichiers de son choix aux noms qu'il souhaite dans /... . Pour une illustration de son utilisation, voyez mon post un peu au dessus de celui-ci.)