table of contents
- bookworm-backports 4.24.0-2~bpo12+1
- testing 4.24.0-2
- unstable 4.24.0-2
Capacités(7) | Miscellaneous Information Manual | Capacités(7) |
NOM¶
capabilities – Présentation des capacités Linux
DESCRIPTION¶
Pour vérifier les permissions, les implémentations UNIX traditionnelles distinguent deux catégories de processus : les processus privilégiés (dont l'UID effectif est 0, appelé superutilisateur ou root) et les processus non privilégiés (dont les UID effectifs sont différents de zéro). Les processus privilégiés contournent toutes les vérifications de permissions du noyau, alors que les processus non privilégiés sont soumis à une vérification complète basée sur l'identification du processus (habituellement : UID effectif, GID effectif et liste des groupes additionnels).
À partir de Linux 2.2, Linux scinde les privilèges traditionnellement associés au superutilisateur en unités distinctes, connues sous le nom de capabilities (capacités) que l'on peut activer ou inhiber individuellement. Les capacités sont des attributs individuels à chaque thread.
Liste des capacités¶
La liste suivante indique les capacités implémentées sous Linux et les opérations ou comportements que chaque capacité permet :
- CAP_AUDIT_CONTROL (depuis Linux 2.6.11)
- Activer et désactiver l'audit du noyau, changer les règles de filtrage d'audit, accéder à l'état de l'audit et aux règles de filtrage.
- CAP_AUDIT_READ (depuis Linux 3.16)
- Autoriser la lecture du journal d'audit au moyen d'un socket netlink multidiffusion.
- CAP_AUDIT_WRITE (depuis Linux 2.6.11)
- Écrire des enregistrements dans le journal d'audit du noyau.
- CAP_BLOCK_SUSPEND (depuis Linux 3.5)
- Utiliser des fonctionnalités qui peuvent bloquer la mise en veille du système (epoll(7) EPOLLWAKEUP, /proc/sys/wake_lock).
- CAP_BPF (depuis Linux 5.8)
- Utiliser des opérations BPF privilégiées ; consultez bpf(2) et bpf-helpers(7).
- Cette capacité a été ajoutée dans Linux 5.8 pour séparer la fonctionnalité BPF de la capacité CAP_SYS_ADMIN surchargée.
- Mettre à jour /proc/sys/kernel/ns_last_pid (consultez pid_namespaces(7)) ;
- Utiliser la fonction set_tid de clone3(2) ;
- Lire le contenu des liens symboliques dans /proc/pid/map_files pour les autres processus.
- Cette capacité a été ajoutée dans Linux 5.9 pour séparer la fonctionnalité checkpoint/restore de la capacité CAP_SYS_ADMIN surchargée.
- CAP_CHOWN
- Effectuer toute modification des UID et GID de fichiers (consultez chown(2)).
- CAP_DAC_OVERRIDE
- Contourner les vérifications des permissions de lecture, écriture et exécution. (DAC est l'abréviation de « discretionary access control », contrôle d'accès à volonté).
- CAP_DAC_READ_SEARCH
- Contourner les vérifications des permissions de lecture de fichiers et celles de lecture et d'exécution des répertoires ;
- invoquer open_by_handle_at(2) ;
- utiliser l'attribut AT_EMPTY_PATH de linkat(2) pour créer un lien vers un fichier visé par un descripteur de fichier.
- Contourner les vérifications pour les opérations qui demandent que l'UID de système de fichiers du processus corresponde à l'UID du fichier (par exemple chmod(2), utime(2)), à l'exclusion des opérations couvertes par CAP_DAC_OVERRIDE et CAP_DAC_READ_SEARCH ;
- positionner les attributs d'inœuds (consultez ioctl_iflags(2)) pour n'importe quel fichier ;
- positionner les listes de contrôle d'accès ACL (« Access Control Lists ») pour n'importe quel fichier ;
- ignorer le « sticky bit » des répertoires pour les suppressions de fichier ;
- modifier les attributs étendus user sur un répertoire avec le sticky bit défini, appartenant à n'importe quel utilisateur ;
- spécifier O_NOATIME dans open(2) et fcntl(2) pour n'importe quel fichier.
- Ne pas effacer les bits de mode set-user-ID et set-group-ID lors de la modification d'un fichier ;
- positionner le bit Set-group-ID sur un fichier dont le GID ne correspond pas au système de fichiers ni à aucun GID additionnel du processus appelant.
- Verrouiller des pages mémoire (mlock(2), mlockall(2), mmap(2), shmctl(2)) ;
- allouer des pages mémoire utilisant des pages larges (memfd_create(2), mmap(2), shmctl(2)).
- CAP_IPC_OWNER
- Contourner les vérifications de permission pour les opérations sur les objets IPC System V.
- CAP_KILL
- Contourner les vérifications de permission pour l'émission de signaux (consultez kill(2)). Cette capacité inclut l'utilisation de l'opération KDSIGACCEPT d'ioctl(2).
- CAP_LEASE (depuis Linux 2.4)
- Demander des baux (leases) sur n'importe quel fichier (consultez fcntl(2)).
- CAP_LINUX_IMMUTABLE
- Positionner les attributs d'inœuds FS_APPEND_FL et FS_IMMUTABLE_FL (consultez ioctl_iflags(2)).
- CAP_MAC_ADMIN (depuis Linux 2.6.25)
- Permettre les modifications de la configuration ou des états MAC. Implémentée pour le module LSM (Smack Linux Security Module).
- CAP_MAC_OVERRIDE (depuis Linux 2.6.25)
- Surcharger les contrôles d'accès MAC (« Mandatory Access Control »). Implémentée pour le module Smack LSM.
- CAP_MKNOD (depuis Linux 2.4)
- Créer des fichiers spéciaux avec mknod(2).
- CAP_NET_ADMIN
- Effectuer diverses opérations liées au réseau :
- configuration des interfaces ;
- administration du pare-feu, de la traduction d'adresse IP (« masquerading ») et collection de données sur le trafic réseau (« accounting ») ;
- modification des tables de routages ;
- attachement à n'importe quelle adresse pour un service mandataire transparent ;
- sélection du type de service (« TOS ») ;
- effacement des statistiques du pilote ;
- sélection du mode « promiscuité » ;
- activation de la diffusion multipoint (« multicast ») ;
- utilisation de setsockopt(2) pour définir les options de sockets suivantes : SO_DEBUG, SO_MARK, SO_PRIORITY (pour une priorité en dehors des valeurs de 0 à 6), SO_RCVBUFFORCE et SO_SNDBUFFORCE.
- CAP_NET_BIND_SERVICE
- Attacher un socket à un port privilégié du domaine de l'Internet (numéro de port inférieur à 1024).
- CAP_NET_BROADCAST
- (Inutilisé) diffusion par socket et écoute de multidiffusion.
- CAP_NET_RAW
- Utiliser des sockets RAW et PACKET ;
- attacher à n'importe quelle adresse pour un service mandataire transparent.
- CAP_PERFMON (depuis Linux 5.8)
- Utiliser divers mécanismes de suivi des performances dont :
- appeler perf_event_open(2) ;
- utiliser diverses opérations BPF qui ont des incidences sur les performances.
- Cette capacité a été ajoutée dans Linux 5.8 pour séparer la fonctionnalité de suivi des performances de la capacité CAP_SYS_ADMIN surchargée. Consultez aussi le fichier source du noyau Documentation/admin-guide/perf-security.rst.
- Faire des manipulations arbitraires des GID et de la liste de GID additionnels des processus ;
- simuler des GID lors du passage de références de sockets au moyen de sockets de domaine UNIX ;
- écrire une projection de GID dans un espace de noms utilisateur (consultez user_namespaces(7)).
- CAP_SETFCAP (depuis Linux 2.6.24)
- Définir des capacités arbitraires sur un fichier
- Depuis Linux 5.12, cette capacité est aussi nécessaire pour projeter l'UID 0 dans un nouvel espace de noms utilisateur ; pour en savoir plus consultez user_namespaces(7).
- CAP_SETPCAP
- Si les capacités de fichier sont prises en charge (c'est-à-dire depuis Linux 2.6.24) : ajouter toute capacité de l'ensemble de limitation de capacités du thread appelant à son ensemble hérité ; supprimer les capacités de l'ensemble de limitation de capacités (avec prctl(2) PR_CAPBSET_DROP) ; modifier les attributs securebits.
- Si les capacités de fichier ne sont pas prises en charge (c'est-à-dire avec les noyaux antérieurs à Linux 2.6.24) : accorder ou interdire toute capacité dans l'ensemble des capacités permises de l'appelant vers ou depuis tout autre processus (cette propriété de CAP_SETPCAP n'est pas disponible quand le noyau est configuré pour prendre en charge les capacités de fichiers, puisque CAP_SETPCAP a une toute autre sémantique pour ces noyaux).
- Faire des manipulations arbitraires des UID de processus (setuid(2), setreuid(2), setresuid(2), setfsuid(2)) ;
- simuler des UID lors du passage de références de sockets au moyen de sockets de domaine UNIX ;
- écrire une projection de l'UID dans un espace de noms utilisateur (consultez user_namespaces(7)).
- CAP_SYS_ADMIN
- Remarque : cette capacité est surchargée : voir les Notes pour les développeurs du noyau ci-dessous.
- Effectuer certaines opérations d'administration système comme : quotactl(2), mount(2), umount(2), pivot_root(2), swapon(2), swapoff(2), sethostname(2) et setdomainname(2) ;
- effectuer des opérations syslog(2) nécessitant des droits (depuis Linux 2.6.37, CAP_SYSLOG doit être utilisée pour permettre de telles opérations) ;
- effectuer une commande VM86_REQUEST_IRQ vm86(2) ;
- accéder à la même fonctionnalité checkpoint/restore qui est contrôlée par CAP_CHECKPOINT_RESTORE (mais cette dernière capacité plus faible est préférée pour accéder à cette fonctionnalité) ;
- effectuer les mêmes opérations BPF que celles contrôlées par CAP_BPF (mais cette dernière capacité plus faible est préférée pour accéder à cette fonctionnalité) ;
- utiliser les mêmes mécanismes de suivi des performances qui sont contrôlés par CAP_PERFMON (mais cette dernière capacité plus faible est préférée pour accéder à cette fonctionnalité) ;
- effectuer des opérations IPC_SET et IPC_RMID sur n'importe quel objet IPC System V ;
- ne pas tenir compte de la limite de ressource RLIMIT_NPROC ;
- effectuer des opérations sur les attributs étendus trusted et security (consultez xattr(7)) ;
- utiliser lookup_dcookie(2) ;
- utiliser ioprio_set(2) pour configurer une classe d'ordonnancement d'E/S IOPRIO_CLASS_RT et (avant Linux 2.6.25) IOPRIO_CLASS_IDLE ;
- simuler des PID lors du passage de références de sockets au moyen de sockets de domaine UNIX ;
- dépasser /proc/sys/fs/file-max, la limite système du nombre de fichiers ouverts dans les appels système qui ouvrent des fichiers (par exemple accept(2), execve(2), open(2) et pipe(2)) ;
- utiliser les attributs CLONE_* qui créent de nouveaux espaces de noms avec clone(2) et unshare(2) (mais, depuis Linux 3.8, la création d'espaces de noms utilisateur ne nécessite aucune capacité) ;
- accéder aux informations d'événements perf nécessitant des droits ;
- appeler setns(2) (nécessite la capacité CAP_SYS_ADMIN dans l'espace de noms target ;
- appeler fanotify_init(2) ;
- effectuer des opérations KEYCTL_CHOWN et KEYCTL_SETPERM de keyctl(2) nécessitant des droits ;
- effectuer une opération madvise(2) MADV_HWPOISON ;
- utiliser la commande TIOCSTI de ioctl(2) pour insérer des caractères dans la file d'entrées d'un terminal autre que le terminal de contrôle de l'appelant ;
- utiliser l'appel système obsolète nfsservctl(2) ;
- utiliser l'appel système obsolète bdflush(2) ;
- effectuer diverses opérations ioctl(2) sur des périphériques bloc nécessitant des droits ;
- effectuer diverses opérations ioctl(2) sur des systèmes de fichiers nécessitant des droits ;
- effectuer des opérations ioctl(2) nécessitant des droits sur le périphérique /dev/random (consultez random(4)) ;
- installer un filtre seccomp(2) sans avoir à définir d'abord l'attribut de thread no_new_privs ;
- modifier les règles d'autorisation ou d'interdiction pour les groupes de contrôle de périphérique ;
- utiliser l'opération PTRACE_SECCOMP_GET_FILTER de ptrace(2) pour vider les filtres seccomp de l'observé ;
- utiliser l'opération PTRACE_SETOPTIONS de ptrace(2) pour suspendre les protections seccomp de l'observé (c'est-à-dire l'attribut PTRACE_O_SUSPEND_SECCOMP) ;
- effectuer des opérations d'administration sur de nombreux pilotes de périphériques ;
- modifier les valeurs de courtoisie de l'autogroupe en écrivant dans /proc/pid/autogroup (consultez sched(7)).
- CAP_SYS_BOOT
- Utiliser reboot(2) et kexec_load(2).
- CAP_SYS_CHROOT
- Charger ou décharger des modules noyaux (consultez init_module(2) et delete_module(2)) ;
- avant Linux 2.6.25 : enlever des capacités de l'ensemble de limitation de capacités au niveau du système.
- Baisser la valeur de courtoisie (« nice ») (nice(2), setpriority(2)) et changer la courtoisie de n'importe quel processus ;
- définir les politiques d'ordonnancement temps réel pour le processus appelant et les politiques d'ordonnancement et les priorités de n'importe quel processus (sched_setscheduler(2), sched_setparam(2), sched_setattr(2)) ;
- définir l'affinité CPU pour n'importe quel processus (sched_setaffinity(2)) ;
- définir la classe et la priorité d'ordonnancement d'entrées/sorties pour n'importe quel processus (ioprio_set(2)) ;
- appliquer migrate_pages(2) à n'importe quel processus et migrer un processus vers n'importe quel nœud ;
- appliquer move_pages(2) pour n'importe quel processus ;
- utiliser l'attribut MPOL_MF_MOVE_ALL avec mbind(2) et move_pages(2).
- CAP_SYS_PACCT
- Utiliser acct(2).
- CAP_SYS_PTRACE
- Suivre n'importe quel processus avec ptrace(2) ;
- appliquer get_robust_list(2) à n'importe quel processus ;
- transférer les données depuis ou vers la mémoire de n'importe quel processus au moyen de process_vm_readv(2) et de process_vm_writev(2) ;
- examiner les processus avec kcmp(2).
- Effectuer des opérations d'entrées-sorties (iopl(2) et ioperm(2)) ;
- accéder à /proc/kcore ;
- utiliser l'opération FIBMAP de ioctl(2) ;
- ouvrir les périphériques pour accéder aux registres spécifiques au modèle (MSR, consultez msr(4)) d'un processeur x86 ;
- mettre à jour /proc/sys/vm/mmap_min_addr ;
- créer des projections en mémoire aux adresses inférieures à la valeur indiquée par /proc/sys/vm/mmap_min_addr ;
- projeter les fichiers dans /proc/bus/pci ;
- ouvrir /dev/mem et /dev/kmem ;
- effectuer diverses commandes de périphérique SCSI ;
- effectuer certaines opérations sur les périphériques hpsa(4) et cciss(4) ;
- effectuer certaines opérations spécifiques à un périphérique sur d'autres périphériques.
- Utiliser de l'espace réservé sur des systèmes de fichiers ext2 ;
- effectuer des appels ioctl(2) pour contrôler la journalisation ext3 ;
- ne pas tenir compte des limites de quota disque ;
- augmenter les limites de ressources (consultez setrlimit(2)) ;
- ne pas tenir compte de la limite de ressource RLIMIT_NPROC ;
- ne pas tenir compte du nombre maximal de consoles sur l'allocation de console ;
- ne pas tenir compte du nombre maximal de dispositions de clavier ;
- permettre des interruptions à plus de 64 Hz depuis l'horloge temps réel ;
- augmenter la limite msg_qbytes pour la file de messages System V au-dessus de la limite /proc/sys/kernel/msgmnb (consultez msgop(2) et msgctl(2)) ;
- permettre le contournement de la limite de ressource RLIMIT_NOFILE sur le nombre de descripteurs de fichiers « en cours » lors de leur transmission à un autre processus au moyen d'un socket de domaine UNIX (consultez unix(7)) ;
- ne pas tenir compte de la limite /proc/sys/fs/pipe-size-max lors du réglage de la capacité d'un tube avec la commande fcntl(2) avec l'argument F_SETPIPE_SZ ;
- utiliser F_SETPIPE_SZ pour augmenter la capacité d'un tube au-dessus de la limite spécifiée par /proc/sys/fs/pipe-max-size ;
- ne pas tenir compte des limites /proc/sys/fs/mqueue/queues_max, /proc/sys/fs/mqueue/msg_max et /proc/sys/fs/mqueue/msgsize_max lors de la création de files de messages POSIX (consultez mq_overview(7)) ;
- utiliser l'opération PR_SET_MM de prctl(2) ;
- affecter à /proc/pid/oom_score_adj une valeur inférieure à la dernière valeur affectée par un processus avec CAP_SYS_RESOURCE.
- CAP_SYS_TIME
- Modifier l'heure système (settimeofday(2), stime(2), adjtimex(2)) ; modifier l'horloge temps réel (matérielle).
- CAP_SYS_TTY_CONFIG
- Utiliser vhangup(2) ; employer diverses opérations ioctl(2) nécessitant des droits sur des terminaux virtuels.
- CAP_SYSLOG (depuis Linux 2.6.37)
- Effectuer des opérations syslog(2) nécessitant des droits. Consultez syslog(2) pour savoir quelles opérations nécessitent des droits.
- Inspecter les adresses du noyau exposées par /proc et d'autres interfaces lorsque /proc/sys/kernel/kptr_restrict a la valeur 1. (Voir la discussion sur kptr_restrict dans proc(5).)
- CAP_WAKE_ALARM (depuis Linux 3.0)
- Déclencher quelque chose qui réveillera le système (réglage des alarmes CLOCK_REALTIME_ALARM et CLOCK_BOOTTIME_ALARM).
Implémentations passées et actuelles¶
Une implémentation complète des capacités nécessite que :
- pour toutes les opérations privilégiées, le noyau doit vérifier si le thread a la capacité requise dans son ensemble effectif ;
- le noyau doit fournir des appels système permettant de changer et récupérer les ensembles de capacités d'un thread ;
- le système de fichiers doit permettre d'attacher des capacités aux fichiers exécutables pour qu'un processus en dispose quand le fichier est exécuté.
Avant Linux 2.6.24, seules les deux premières exigences sont remplies ; depuis Linux 2.6.24, ces trois exigences sont remplies.
Remarques pour les développeurs du noyau¶
Lors de l'ajout d'une nouvelle fonctionnalité du noyau qui pourrait être contrôlée par une capacité, veuillez prendre en considération les points suivants :
- Le but des capacités est de découper le pouvoir du superutilisateur en plusieurs aptitudes de telle sorte que si un programme qui a une ou plusieurs capacités est compromis, son pouvoir d'endommager le système soit moindre que si le programme est exécuté avec les privilèges du superutilisateur.
- Vous pouvez choisir de créer une nouvelle capacité pour votre nouvelle fonctionnalité, ou d'associer la fonctionnalité à l'une des capacités existantes. Afin que l'ensemble des capacités garde une taille gérable, la seconde solution est préférable, à moins qu'il y ait des raisons convaincantes de choisir la première option (il existe aussi une limite technique : la taille des ensembles de capacités est actuellement limitée à 64 bits).
- Pour déterminer parmi les capacités existantes laquelle est la mieux adaptée pour être associée à la nouvelle fonctionnalité, examinez la liste de capacités ci-dessus pour trouver un « silo » dans lequel la nouvelle capacité est la mieux adaptée. Une des options est de déterminer s'il y a d'autres fonctionnalités exigeant des capacités qui seront toujours utilisées avec la nouvelle fonctionnalité. Si la nouvelle fonctionnalité ne sert à rien sans les autres fonctions, vous devriez utiliser la même capacité que ces autres fonctions.
- Ne choisissez pas CAP_SYS_ADMIN si vous pouvez l'éviter ! Une forte proportion de vérifications de capacités existantes lui sont associée (voir une liste partielle plus haut). Elle pourrait plausiblement être appelée « la nouvelle racine », dans la mesure où d'une part, elle confère une large palette de pouvoirs, et d'autre part, sa vaste portée signifie que c'est la capacité qui est requise par de nombreux programmes privilégiés. Ne rendez pas le problème encore plus compliqué. Les seules nouvelles fonctionnalités qui pourraient être associées à CAP_SYS_ADMIN sont celles qui correspondent de façon étroite aux usages existants dans ce silo.
- Si vous avez établi qu'il était réellement nécessaire de créer une nouvelle capacité pour votre fonctionnalité, ne la créez pas ou ne la nommez pas comme une capacité « à usage unique ». Par conséquent, par exemple, l'ajout de la capacité très spécifique CAP_SYS_PACCT était probablement une erreur. Essayez plutôt d'identifier et de nommer votre nouvelle capacité comme un silo plus général dans lequel d'autres futures cas d'usage semblable pourraient s'intégrer.
Ensembles de capacités des threads¶
Chaque thread a les ensembles de capacités suivants contenant zéro ou plus des capacités ci-dessus :
- Permitted (permis)
- Il s'agit d'un surensemble limitant les capacités effectives que le thread peut prendre. Il limite également les capacités qui peuvent être ajoutées à l'ensemble héritable par un thread qui n'a pas la capacité CAP_SETPCAP dans son ensemble effectif.
- Si un processus supprime une capacité de son ensemble de capacités permises, il ne peut plus jamais la récupérer (sauf s'il appelle execve(2) sur un programme set-user-ID-root ou un programme dont les capacités associées au fichier accordent cette capacité).
- Inheritable (héritable)
- Il s'agit d'un ensemble de capacités préservées au travers d'un execve(2). Les capacités héritables restent héritables lors de l'exécution d'un programme et les capacités héritables sont ajoutées à l'ensemble de capacités permises lors de l'exécution d'un programme qui a les bits correspondant activés dans l'ensemble héritable du fichier.
- Parce que les capacités héritables ne sont généralement pas préservées au travers d'un execve(2) lors d'une exécution en tant qu'utilisateur ordinaire, les applications qui souhaitent exécuter des programmes d'assistance avec des capacités plus élevées devraient envisager d'utiliser les capacités ambiantes, décrites ci-dessous.
- Effective (effectif)
- Il s'agit de l'ensemble des capacités utilisées par le noyau pour vérifier les permissions du thread.
- Bounding (limitation) (par processus depuis Linux 2.6.25)
- L’ensemble de limitation des capacités (« capability bounding set ») est un mécanisme qui peut être utilisé pour limiter les capacités qui peuvent être obtenues lors d'un execve(2).
- Depuis Linux 2.6.25, c'est un ensemble de capacités par thread. Dans les noyaux plus anciens, la limitation des capacités était un attribut pour l'ensemble du système, partagé par tous les threads du système.
- Pour plus de détails, voir Ensemble de limitation des capacités, ci-dessous.
- Ambient (ambiant) (depuis Linux 4.3)
- Il s'agit d'un ensemble de capacités préservées au travers d'un execve(2) d'un programme non privilégié. L'ensemble de capacités ambiantes obéit à la règle invariable qu'aucune capacité ne peut être ambiante si elle n'est pas à la fois permise et héritable.
- L'ensemble de capacités ambiantes peut être directement modifié avec prctl(2). Les capacités ambiantes sont automatiquement diminuées si une capacités soit permises soit héritables correspondantes sont diminuées.
- L'exécution d'un programme qui change l'UID ou le GID à cause des bits set-user-ID ou set-group-ID, ou l'exécution d'un programme qui a un ensemble de capacités de fichier supprimera l'ensemble ambiant. Les capacités ambiantes sont ajoutées à l'ensemble des capacités permises et assignées à l'ensemble des capacités effectives quand execve(2) est appelé. Si les capacités ambiantes font que les capacités permises et ambiantes d'un processus sont accrues durant un execve(2), cela ne déclenche pas le mode « secure-execution » décrit dans ld.so(8).
Un enfant créé par fork(2) hérite d'une copie des ensembles de capacités de son parent. Pour des détails sur la façon dont execve(2) affecte les capacités, voir Transformation des capacités lors d'un appel execve() plus bas.
En utilisant capset(2), un thread peut manipuler ses propres ensembles de capacités ; voir Ajuster les ensembles de capacités par programmation ci-dessous).
À partir de Linux 3.2, le fichier /proc/sys/kernel/cap_last_cap contient la valeur numérique de la capacité la plus élevée qui soit acceptée par le noyau en cours d'exécution ; cette valeur peut être utilisée pour déterminer le bit le plus élevé qui puisse être défini dans un ensemble de capacités.
Capacités de fichier¶
Depuis Linux 2.6.24, le noyau prend en charge l'association d'ensembles de capacités avec un fichier exécutable à l'aide de setcap(8). Les ensembles de capacités du fichier sont stockés dans un attribut étendu (consultez setxattr(2) et xattr(7)) appelé security.capability. Écrire dans cet attribut étendu nécessite la capacité CAP_SETFCAP. Les ensembles de capacités d'un fichier, combinés avec les ensembles de capacités du thread, déterminent les capacités d'un thread après un execve(2).
Les trois ensembles de capacités de fichier sont :
- Permitted (anciennement forced (forcé)) :
- Ces capacités sont automatiquement permises au thread, quelles que soient ses capacités héritables.
- Inheritable (anciennement allowed (autorisé)) :
- Cet ensemble est combiné par un ET avec l'ensemble héritable du thread pour savoir quelles capacités de l'ensemble des capacités héritables sont permises dans l’ensemble permis du thread après l'appel à execve(2).
- Effective (effectif) :
- Il ne s'agit pas d'un ensemble, mais plutôt d'un unique bit. Si le bit est positionné, alors, lors d'un execve(2), toutes les nouvelles capacités permises pour le thread sont également positionnées dans l'ensemble effectif. Si ce bit n'est pas positionné, alors, après un execve(2), aucune des nouvelles capacités permises ne se trouvera dans le nouvel ensemble effectif.
- Activer le bit des capacités effectives d'un fichier implique que toute capacité de fichier permise ou héritable qui permet à un thread d'obtenir les capacités permises correspondantes lors d'un execve(2) (consultez Transformation des capacités lors d'un appel execve() ci-dessous) fera que ce fichier aura aussi cette capacité dans son ensemble effectif. Ainsi, lors de l'ajout de capacités à un fichier (setcap(8), cap_set_file(3), cap_set_fd(3)), si l’attribut effectif pour une des capacités est activé, alors l'attribut effectif doit également être activé pour toutes les autres capacités dont l’attribut permis ou héritable correspondant est activé.
Versionnage d'attributs étendus de capacité de fichier¶
Pour permettre l'extensibilité, le noyau prend en charge un système pour coder un numéro de version dans l'attribut étendu security.capability qui est utilisé pour implémenter les capacités de fichier. Ces numéros de version sont intégrés à l'implémentation et pas directement visibles aux applications de l'espace utilisateur. À ce jour, les versions suivantes sont prise en charge :
- VFS_CAP_REVISION_1
- C'était l'implémentation d'origine de la capacité de fichier qui prenait en charge les masques 32 bits pour les capacités de fichier.
- VFS_CAP_REVISION_2 (depuis Linux 2.6.25)
- Cette version permet des masques de capacité de fichier d'une taille de 64 bits, ce qui était nécessaire, car le nombre de capacités prises en charge dépassait 32. Le noyau continue de façon transparente à prendre en charge l'exécution de fichiers qui ont des masques de capacité version 1 32 bits, mais lors de l'ajout de capacités à des fichiers qui n'avaient pas encore de capacités ou lors de la modification des capacités de fichiers existants, il utilise automatiquement le système de la version 2 (ou éventuellement la version 3, comme décrit plus bas).
- VFS_CAP_REVISION_3 (depuis Linux 4.14)
- Les capacités de fichier version 3 sont fournies pour prendre en charge les capacités de fichier mises dans un espace de noms (décrites plus bas).
- Comme avec les capacités de fichier version 2, les masques de capacité version 3 ont une longueur de 64 bits. Mais en complément, l'UID root de l'espace de noms est codé dans l'attribut étendu security.capability (un UID root d'espace de noms est la valeur à laquelle l'UID 0 dans cet espace de noms correspond dans l'espace de noms utilisateur initial).
- Les capacités de fichier version 3 sont conçues pour coexister avec les capacités version 2 ; c'est-à-dire que, sur un système Linux moderne, il peut y avoir certains fichiers avec des capacités version 2 tandis que d'autres ont des capacités version 3.
Avant Linux 4.14, le seul type d'attribut étendu de capacité de fichier qui pouvait être attaché à un fichier était un attribut VFS_CAP_REVISION_2. Depuis Linux 4.14, la version de l'attribut étendu security.capability attaché à un fichier dépend des circonstances dans lesquelles l'attribut a été créé.
À partir de Linux 4.14, un attribut étendu security.capability est créé automatiquement (ou converti) en attribut version 3 (VFS_CAP_REVISION_3) si les deux conditions suivantes sont vraies :
- Le thread qui écrit l'attribut réside dans un espace de noms utilisateur non initial (plus précisément, le thread réside dans un espace de noms utilisateur autre que celui à partir duquel le système de fichiers sous-jacent a été monté).
- Le thread a la capacité CAP_SETFCAP sur l'inœud du fichier, ce qui veut dire que (a) le thread a la capacité CAP_SETFCAP dans son propre espace de noms utilisateur et (b) l'UID et le GID de l'inœud du fichier a des correspondances dans l'espace de noms utilisateur de celui qui écrit.
Quand un attribut étendu security.capability VFS_CAP_REVISION_3 est créé, l'UID root de l'espace de noms utilisateur du thread qui crée l'attribut est enregistré dans l'attribut étendu.
Par contre, la création ou la modification d'un attribut étendu security.capability à partir d'un thread privilégié (CAP_SETFCAP) qui réside dans l'espace de noms où le système de fichiers sous-jacent a été monté (ce qui correspond normalement à l'espace de noms utilisateur initial) a automatiquement pour conséquence la création d'un attribut version 2 (VFS_CAP_REVISION_2).
Veuillez noter que la création d'un attribut étendu security.capability version 3 est automatique. C'est-à-dire que losrsqu'une application de l'espace utilisateur écrit (setxattr(2)) un attribut security.capability au format de la version 2, le noyau créera automatiquement un attribut version 3 si l'attribut est créé dans les conditions décrites plus haut. En parallèle, quand un attribut security.capability version 3 est récupéré (getxattr(2)) par un processus qui réside dans un espace de noms utilisateur qui a été créé par l'UID root (ou un descendant de cet espace de noms utilisateur), l'attribut renvoyé est (automatiquement) simplifié pour apparaître comme un attribut version 2 (c'est-à-dire que la valeur renvoyée est la taille de l'attribut version 2 et n'inclut pas l'UID root). Ces transpositions automatiques signifient qu'aucune modification n'est requise pour les outils de l'espace utilisateur (par exemple setcap(1) getcap(1)) pour que ces outils soient utilisés pour créer et récupérer des attributs security.capability version 3.
Veuillez noter qu'un fichier peut se voir associé un attribut étendu security.capability version 2 ou version 3, mais pas les deux à la fois : la création ou la modification de l'attribut étendu security.capability modifiera automatiquement la version selon les conditions dans lesquelles l'attribut étendu est créé ou modifié.
Transformation des capacités lors d'un appel execve()¶
Durant un execve(2), le noyau calcule les nouvelles capacités du processus en utilisant l'algorithme suivant :
P'(ambient) = (le fichier est privilégié) ? 0 : P(ambient) P'(permitted) = (P(inheritable) & F(inheritable)) |
(F(permitted) & P(bounding)) | P'(ambient) P'(effective) = F(effective) ? P'(permitted) : P'(ambient) P'(inheritable) = P(inheritable) [c'est-à-dire inchangé] P'(bounding) = P(bounding) [c'est-à-dire inchangé]
où :
Veuillez noter les détails suivants concernant les règles de transformation de capacités ci-dessus :
- L'ensemble de capacités ambiantes est présent seulement depuis Linux 4.3. Lors de la détermination de la transformation de l'ensemble ambiant durant un execve(2), un fichier privilégié est un fichier qui a des capacités ou le bit set-user-ID ou le bit set-group-ID positionné.
- Avant Linux 2.6.25, l'ensemble de limitation de capacités était un attribut au niveau du système, partagé par tous les threads. Cette valeur au niveau du système était employée pour calculer le nouvel ensemble de capacités permises durant un execve(2) de la même manière que cela est montré plus haut pour P(bounding).
Note : durant les transitions de capacité décrite plus haut, les capacités de fichier peuvent être ignorées (traitées comme si elles étaient vides) pour les mêmes raisons que les bits set-user-ID et set-group-ID sont ignorés ; voir execve(2). Les capacités de fichier sont ignorées de la même manière si le noyau a été lancé avec l'option no_file_caps.
Note : conformément aux règles ci-dessus, si un processus avec des UID différents de zéro exécutent un execve(2), alors toutes les capacités présentes dans son ensemble de capacités permises et effectives seront supprimées. Pour le traitement de capacités quand un processus avec un UID de zéro exécute un execve(2), consultez ci-dessous Capacités et exécution de programmes par le superutilisateur.
Vérification de sécurité pour les binaires passives aux capacités¶
Un binaire passif aux capacités est une application qui a été marquée pour avoir des capacités de fichier, mais n'a pas été convertie pour utiliser l'API libcap(3) pour manipuler ses capacités (en d'autres mots, c'est un programme set-user-iD-root traditionnel qui a été modifié pour utiliser des capacités de fichier, mais dont le code n'a pas été modifié pour comprendre les capacités). Pour ce type d'application, le bit de capacité effective est défini sur le fichier, de telle sorte que les capacités de fichier permises soient activées automatiquement dans l'ensemble de capacités effectives du processus lors de l'exécution du fichier. Le noyau reconnaît un fichier qui a un bit de capacité effective défini comme passif aux capacités en vue de la vérification décrite ici.
Lors de l'exécution d'un binaire passif aux capacités, le noyau vérifie si le processus a obtenu toutes les capacités permises qui sont spécifiées dans l'ensemble de capacités permises de fichier, après que les transformations de capacité décrites plus haut ont été exécutées (la raison habituelle pour laquelle cela pourrait ne pas se produire est que l'ensemble de limitation de capacités a interdit certaines des capacités dans l'ensemble de capacités permises de fichier). Si le processus n'obtient pas l'ensemble complet de capacités permises de fichier, alors l'execve(2) échoue avec l'erreur EPERM. Cela évite de possibles risques de sécurité qui pourraient survenir quand une application passive aux capacités est exécutée avec moins de privilèges que nécessaire. Notez que, par définition, l'application ne pourrait pas reconnaître elle-même ce problème, dans la mesure où elle n'emploie pas l'API libcap(3).
Capacités et exécution de programmes par le superutilisateur¶
Afin de refléter les sémantiques traditionnelles d'UNIX, le noyau effectue un traitement particulier des capacités de fichier quand un processus avec l'UID 0 (superutilisateur) exécute un programme et quand un programme set-user-ID-root est exécuté.
Après avoir réalisé toutes les modifications de l'ID effectif du processus qui ont été déclenchées par le bit de mode set-user-ID du binaire (par exemple, le changement de l'UID à 0 (superutilisateur) parce qu'un programme set-user-ID-root a été exécuté), le noyau calcule les ensembles de capacités de fichier comme suit :
- (1)
- Si l'UID réel ou effectif du processus est 0 (superutilisateur), alors les ensembles de capacités héritables et permises de fichier sont ignorés ; ils sont plutôt considérés théoriquement comme remplis de uns (c'est-à-dire, toutes les capacités activées). Il y a une exception à ce comportement, décrite ci-dessous dans la section Programmes set-user-ID-root qui ont des capacités de fichier.
- (2)
- Si l'UID effectif du processus est 0 (superutilisateur) ou le bit des capacités effectives du fichier est en fait activé, alors le bit des capacités effectives du fichier est théoriquement défini à un (activé).
Ces valeurs théoriques pour les ensembles de capacités de fichier sont alors utilisées comme décrites ci-dessus pour calculer la transformation des capacités du processus durant l'execve(2).
Alors, quand un processus avec des UID différents de zéro appelle execve(2) sur un programme set-user-ID-root qui n'a pas de capacités attachées ou quand un processus dont les UID réel et effectif sont zéro applique execve(2) sur un programme, le calcul des nouvelles capacités permises du processus est simplifié à :
P'(permitted) = P(inheritable) | P(bounding) P'(effective) = P'(permitted)
En conséquence, le processus obtient toutes les capacités dans ses ensembles de capacités permises et effectives, à l'exception de celles supprimées par l'ensemble de limitation de capacités (dans le calcul de P'(permitted), le terme P'(ambient) peut être simplifié parce qu'il est par définition un sous-ensemble propre de P(inheritable)).
Les traitements particuliers de l'UID 0 (superutilisateur) décrits dans cette sous-section peuvent être désactivés en utilisant le mécanisme de « securebits » décrit plus bas.
Les programmes set-user-ID-root qui ont des capacités de fichier¶
Il y a une exception au comportement décrit dans Capacités et exécution de programmes par le superutilisateur ci-dessus. Si (a) le binaire qui est en cours d'exécution a des capacités attachées, (b) l'UID réelle du processus n'est pas 0 (supertutilisateur) et (c) l'UID effectif du processus est 0 (superutilisateur), alors les bits de capacité de fichier sont honorés (c'est-à-dire qu'ils ne sont pas théoriquement considérés comme remplis de uns). La circonstance habituelle dans laquelle cette situation peut se produire est lors de l'exécution d'un programme set-user-ID-root qui a aussi les capacités de fichier. Quand un programme de ce type est exécuté, le processus obtient simplement les capacités accordées par le programme (c'est-à-dire pas toutes les capacités comme cela pourrait se produire lors de l'exécution d'un programme set-user-ID-root qui ne possède aucune capacité de fichier associée).
Notez qu'il est possible d'assigner un ensemble de capacités vide à un fichier de programme et donc qu'il est possible de créer un programme set-user-ID-root qui modifie en 0 le set-user-ID effectif et sauvegardé du processus qui exécute le programme, mais ne confère aucune capacité à ce processus.
Ensemble de limitation des capacités¶
L’ensemble de limitation des capacités (« capability bounding set ») est un mécanisme de sécurité qui peut être utilisé pour limiter les capacités qui peuvent être obtenues lors d'un execve(2). L’ensemble de limitation de capacités est utilisé de cette façon :
- Lors d'un execve(2), l’ensemble de limitation de capacités est combinée par un ET binaire avec l'ensemble des capacités autorisées du fichier, et le résultat de cette opération est placé dans l'ensemble des capacités autorisées du thread. L’ensemble de limitation de capacités permet donc de limiter les capacités permises qui peuvent être accordées par un fichier exécutable.
- (Depuis Linux 2.6.25) L’ensemble de limitation de capacités agit comme un surensemble limitant les capacités qu'un thread peut ajouter à son ensemble de capacités héritables en utilisant capset(2). Cela signifie que si une capacité ne se trouve pas dans l'ensemble de limitation des capacités, alors un thread ne peut ajouter cette capacité dans son ensemble de capacités héritables, même si elle se trouvait dans son ensemble de capacités permises, et ne peut donc pas conserver cette capacité dans son ensemble de capacités permises lorsqu'il exécute avec execve(2) un fichier qui a cette capacité dans son ensemble de capacités héritables.
Notez que l’ensemble de limitation de capacités masque les capacités permises du fichier, mais pas les capacités héritées. Si un thread conserve une capacité dans son ensemble de capacités héritées et que cette capacité ne se trouve pas dans l'ensemble de limitation des capacités, alors il peut toujours obtenir cette capacité dans son ensemble de capacités permises en exécutant un fichier qui a la capacité dans son ensemble de capacités héritées.
Suivant la version du noyau, l’ensemble de limitation de capacités est un attribut au niveau du système ou un attribut par processus.
Ensemble de limitation de capacités après Linux 2.6.25
Depuis Linux 2.6.25, l’ensemble de limitation de capacités est un attribut par thread. (L'ensemble de limitation de capacités au niveau du système décrite ci-dessous n'existe plus.)
L’ensemble de limitation est hérité du parent du thread au travers d'un fork(2) et est préservé au travers d'un execve(2).
Un thread peut enlever des capacités de son ensemble de limitation de capacités en utilisant l'opération PR_CAPBSET_DROP de prctl(2), à condition qu'il possède la capacité CAP_SETPCAP. Une fois qu'une capacité a été supprimée de l'ensemble de limitation, elle ne peut y être remise. Un thread peut déterminer si une capacité est dans son ensemble de limitation de capacités en utilisant l'opération PR_CAPBSET_READ de prctl(2).
La suppression de capacités dans l'ensemble de limitation des capacités n'est prise en charge que si les capacités de fichier sont compilées dans le noyau. Avant Linux 2.6.33, les capacités de fichier étaient une fonctionnalité optionnelle configurable ua moyen de l'option CONFIG_SECURITY_FILE_CAPABILITIES. Depuis Linux 2.6.33, l'option de configuration a été supprimée et les capacités de fichier font maintenant toujours partie du noyau. Quand les capacités de fichier sont compilées dans le noyau, le processus init (l'ancêtre de tous les processus) démarre avec un ensemble de limitation complet. Si les capacités de fichier ne sont pas compilées dans le noyau, init démarre alors avec un ensemble de limitation complet, à l'exception de CAP_SETPCAP, parce que cette capacité a une autre signification quand il n'y a pas de capacités de fichier.
Supprimer une capacité de l’ensemble de limitation de capacités ne la supprime pas de l'ensemble héritable d'un thread. Cependant, il empêche de rajouter la capacité dans l'ensemble héritable du thread par la suite.
Ensemble de limitation de capacités avant Linux 2.6.25
Avant Linux 2.6.25, l’ensemble de limitation de capacités est un attribut au niveau du système qui affecte tous les threads. L’ensemble de limitation de capacités est accessible par le fichier /proc/sys/kernel/cap-bound (le masque de bits est exprimé comme un nombre décimal signé dans /proc/sys/kernel/cap-bound, ce qui entretient les confusions).
Seul le processus init peut configurer des capacités dans l'ensemble de limitation de capacités ; en dehors de cela, le superutilisateur (plus précisément : un processus avec la capacité CAP_SYS_MODULE) peut uniquement supprimer des capacités de cet ensemble.
Sur un système standard, l’ensemble de limitation élimine toujours la capacité CAP_SETPCAP. Pour supprimer cette restriction (attention, c'est dangereux !), modifiez la définition de CAP_INIT_EFF_SET dans include/linux/capability.h et recompilez le noyau.
L’ensemble de limitation de capacités pour tout le système a été ajoutée à Linux 2.2.11.
Effet des modifications d'UID sur les capacités¶
Afin de préserver la sémantique traditionnelle pour les transitions entre des UID 0 et des UID différents de zéro, le noyau modifie les ensembles de capacités d'un thread de la façon suivante lors de modifications des UID réel, effectif, sauvegardé et du système de fichiers (avec setuid(2), setresuid(2) et compagnie) :
- Si un ou plus des UID réels, effectifs ou sauvés étaient égal à 0, et qu'à la suite de la modification d'UID, tous ces ID ont une valeur différente de zéro, et toutes les capacités sont supprimées des ensembles de capacités permises, effectives et ambiantes.
- Si l'UID effectif était 0 et devient différent de zéro, toutes les capacités sont supprimées de l'ensemble effectif.
- Si l'UID effectif est modifié d'une valeur différente de zéro à 0, l'ensemble des capacités permises est copié dans l'ensemble des capacités effectives.
- Si l’UID du système de fichiers est modifié de 0 à une valeur différente de zéro (consultez setfsuid(2)), les capacités suivantes sont supprimées de l'ensemble effectif : CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_LINUX_IMMUTABLE (depuis Linux 2.6.30), CAP_MAC_OVERRIDE et CAP_MKNOD (depuis Linux 2.6.30). Si l’UID du système de fichiers devient 0, chacune de ces capacités est activée dans l'ensemble des capacités effectives si elle faisait partie de l'ensemble des capacités permises.
Si un thread qui a une valeur 0 pour un ou plus de ses UID ne veut pas que son ensemble de capacités permises soit vidé lorsqu'il redéfinit tous ses UID à des valeurs non nulles, il peut le faire avec l'attribut « securebits » de SECBIT_KEEP_CAPS décrit ci-dessous.
Ajuster les ensembles de capacités par programmation¶
Un thread peut obtenir ou modifier ses ensembles de capacités permises, effectives et héritées en utilisant les appels système capget(2) et capset(2). Cependant, il faut leur préférer l'utilisation de cap_get_proc(3) et cap_set_proc(3), toutes deux fournies par le paquet libcap. Les règles suivantes gouvernent les modifications des ensembles de capacités d'un thread :
- Si l'appelant n'a pas la capacité CAP_SETPCAP, le nouvel ensemble des capacités héritables doit être un sous-ensemble de l'union des ensembles de capacités héritables et des capacités permises.
- (Depuis Linux 2.6.25) Le nouvel ensemble héritable doit être un sous-ensemble de l'ensemble héritable existant et de l'ensemble de limitation de capacités.
- Le nouvel ensemble des capacités permises doit être un sous-ensemble de l'ensemble des capacités permises existant (c'est-à-dire qu'il n'est pas possible d'obtenir des capacités permises que le thread n'a pas actuellement).
- Le nouvel ensemble effectif doit être un sous-ensemble du nouvel ensemble des capacités permises.
Les attributs « securebits » : configuration d'un environnement restreint aux capacités de fichier.¶
À partir de Linux 2.6.26, si les capacités de fichier sont activées dans le noyau, Linux implémente un ensemble d'attributs securebits par thread qui peuvent être utilisés pour désactiver la gestion particulière des capacités pour l'UID 0 (root). Ces attributs sont les suivants :
- SECBIT_KEEP_CAPS
- Activer cet attribut permet à un thread qui a un UID (ou plus) égal à 0 de conserver ses capacités dans son ensemble des capacités permises quand il change tous ses UID et que plus aucun n'est zéro. Si cet attribut est désactivé, alors ces changements d'UID feront perdre au thread toutes ses capacités permises. Cet attribut est toujours désactivé lors d'un execve(2).
- Notez que même quand l'attribut SECBIT_KEEP_CAPS est actif, les capacités effectives d'un thread sont supprimées quand il change son UID effectif pour une valeur différente de zéro. Néanmoins, si le thread a activé cet attribut et que son UID effectif est déjà différent de zéro et si le thread change ensuite tous les autres UID pour des valeurs différentes de zéro, alors, les capacités effectives ne seront pas supprimées.
- L'activation de l'attribut SECBIT_KEEP_CAPS est ignorée si l'attribut SECBIT_NO_SETUID_FIXUP est actif (ce dernier attribut fournit un surensemble des effets de l'attribut précédent).
- Cet attribut fournit la même fonctionnalité que l'ancienne opération PR_SET_KEEPCAPS de prctl(2).
- SECBIT_NO_SETUID_FIXUP
- Activer cet attribut stoppe l'ajustement des ensembles de capacités permises, effectives et ambiantes du processus par le noyau lorsque les UID effectifs et du système de fichiers du thread passent d'une valeur zéro à une valeur différente de zéro. Consultez Effet des modifications d'UID sur les capacités plus haut.
- SECBIT_NOROOT
- Si cet attribut est activé, alors le noyau n'accorde pas les capacités lorsqu'un programme set-user-ID-root est exécuté ou lorsqu'un processus dont l'UID effectif ou réel est zéro appelle execve(2) (consultez Capacités et exécution de programmes par le superutilisateur ci-dessus).
- SECBIT_NO_CAP_AMBIENT_RAISE
- Activer cet attribut désactive l'élévation des capacités ambiantes au moyen de l'opération PR_CAP_AMBIENT_RAISE de prctl(2).
Chacun des attributs de « base » ci-dessus a un attribut compagnon « verrouillé ». L'activation d'un attribut « verrouillé » est irréversible et permet d'éviter toute modification ultérieure de l'attribut de « base » correspondant. Les attributs « verrouillé » sont : SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED, SECBIT_NOROOT_LOCKED et SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED.
Les attributs securebits peuvent être modifiés et récupérés en utilisant les opérations PR_SET_SECUREBITS et PR_GET_SECUREBITS de prctl(2). La capacité CAP_SETPCAP est nécessaire pour modifier ces attributs. Notez que les constantes SECBIT_* ne sont disponibles qu'après l'inclusion du fichier d'en-tête <linux/securebits.h>.
Les attributs securebits sont hérités par les processus enfants. Lors d'un execve(2), tous les attributs sont conservés, à l'exception de SECBIT_KEEP_CAPS qui est toujours désactivé.
Une application peut utiliser l'appel suivant pour se verrouiller elle-même, ainsi que tous ses descendants, dans un environnement où la seule façon d'obtenir des capacités est d'exécuter un programme avec les capacités de fichiers associées :
prctl(PR_SET_SECUREBITS,
/* SECBIT_KEEP_CAPS désactivé */
SECBIT_KEEP_CAPS_LOCKED |
SECBIT_NO_SETUID_FIXUP |
SECBIT_NO_SETUID_FIXUP_LOCKED |
SECBIT_NOROOT |
SECBIT_NOROOT_LOCKED);
/* Activation/verrouillage de SECBIT_NO_CAP_AMBIENT_RAISE
non requis */
Programmes « set-user_ID-root » par espace de noms utilisateur¶
Un programme set-user-ID dont l'UID correspond à l'UID qui a créé par un espace de noms utilisateur donnera des capacités dans les ensembles de capacités permises et effectives du processus lorsqu'il était utilisé par un processus dans l'espace de noms ou tout espace de noms utilisateur qui en est issu.
Les règles de transformation des capacités du processus pendant un execve(2) sont exactement comme décrites dans Transformation des capacités lors d'un appel execve() et Capacités et exécution de programmes par le superutilisateur ci-dessus;à la différence que, dans la seconde sous-section, « root » est l'UID du créateur de l'espace de noms utilisateur.
Capacités de fichier mises dans un espace de noms¶
Les capacités de fichier traditionnelles (c'est-à-dire version 2) n'associent qu'un ensemble de masques de capacité à un fichier binaire exécutable. Quand un processus exécute un binaire avec des capacités de ce type, il obtient les capacités associées (dans son espace de noms utilisateur) comme pour les règles décrites ci-dessus dans Transformation des capacités lors d'un appel execve().
Étant donné que les capacités de fichier version 2 confèrent des capacités pour l'exécution de processus quel que soit l'espace de noms utilisateur dans lequel il réside, seuls les processus privilégiés ont le droit d'associer des capacités avec un fichier. Ici, « privilégié » veut dire un processus qui a la capacité CAP_SETFCAP dans l'espace de noms utilisateur où le système de fichiers a été monté (normalement, l'espace de noms initial de l'utilisateur). Cette limitation rend les capacités de fichier inutiles dans certains cas d'usage. Par exemple, dans les conteneurs d'un espace de noms utilisateur, il peut être souhaitable de pouvoir créer un binaire qui confère des capacités uniquement au processus exécuté dans ce conteneur, mais pas aux processus exécutés en dehors du conteneur.
Linux 4.14 a ajouté des capacités de fichier appelées « mises dans un espace de noms » pour gérer ce genre de cas d'usage. Les capacités de fichier mises dans un espace de noms sont enregistrées en tant qu'attribut étendu security.capability version 3 (c'est-à-dire VFS_CAP_REVISION_3). Un attribut de ce type est créé automatiquement dans les circonstances décrites ci-dessus dans Versionnage d'attributs étendus de capacité de fichier. Quand un attribut étendu security.capability version 3 est créé, le noyau n'enregistre pas que les masques de capacité dans l'attribut étendu, mais aussi l'UID root de l'espace de noms.
Comme c'est le cas avec un binaire qui possède des capacités de fichier VFS_CAP_REVISION_2, un binaire avec des capacités de fichier VFS_CAP_REVISION_3 confère des capacités à un processus durant un execve(). Néanmoins, ces capacités ne sont conférées que si le processus est exécuté par un processus qui réside dans un espace de noms utilisateur dont l'UID 0 correspond à l'UID root qui est sauvegardé dans l'attribut étendu, ou quand il est exécuté par un processus qui réside dans un descendant de ce type d'espace de noms.
Interaction avec les espaces de noms¶
Pour en savoir plus sur les interactions entre les capacités et les espaces de noms utilisateur, consultez user_namespaces(7).
STANDARDS¶
Il n'y a pas de véritable norme pour les capacités, mais l'implémentation de Linux est basée sur une interprétation de l’avant-projet de norme (retiré) POSIX.1e https://archive.org/details/posix_1003.1e-990310.
NOTES¶
Quand vous tentez de suivre avec strace(1) des binaires qui ont des capacités (ou des binaires set-user-UID-root), vous pouvez trouver l'option -u <username>. Quelque chose comme ceci :
$ sudo strace -o trace.log -u ceci ./mon_prog_privé
De Linux 2.5.27 à Linux 2.6.26, les capacités étaient un composant optionnel du noyau et pouvaient être activées ou désactivées avec l'option de configuration CONFIG_SECURITY_CAPABILITIES du noyau.
Le fichier /proc/pid/task/TID/status peut être utilisé pour voir les ensembles de capacités d'un thread. Le fichier /proc/pid/status indique les ensembles de capacités du thread principal d'un processus. Avant Linux 3.8, les capacités inexistantes étaient vues comme activées (1) dans ces ensembles. Depuis Linux 3.8, toutes les capacités inexistantes (supérieures à la valeur de CAP_LAST_CAP) sont vues comme désactivées (0).
Le paquet libcap fournit un ensemble de routines pour
écrire et connaître les capacités d'un processus de
manière plus simple et moins susceptible de changer que l'interface
fournie par capset(2) et capget(2). Ce paquet fournit
également les programmes setcap(8) et getcap(8). Il
peut être trouvé à l'adresse :
https://git.kernel.org/pub/scm/libs/libcap/libcap.git/refs/.
Avant Linux 2.6.24, et de Linux 2.6.24 à Linux 2.6.32, si les capacités de fichier ne sont pas activées, un thread avec la capacité CAP_SETPCAP peut manipuler les capacités des autres threads. Cependant, ce n'est possible qu'en théorie puisqu'aucun thread n'a la capacité CAP_SETPCAP dans un des cas suivants :
- Dans l'implémentation antérieure au noyau 2.6.25, l'ensemble de limitation de capacités du système, /proc/sys/kernel/cap-bound, masque toujours la capacité CAP_SETPCAP et cela ne peut pas être changé sans modifier les sources du noyau et le recompiler.
- Si les capacités de fichier sont désactivées (c'est-à-dire si l'option CONFIG_SECURITY_FILE_CAPABILITIES du noyau est désactivée), alors init démarre sans la capacité CAP_SETPCAP dans l'ensemble de limitation de capacités par processus, et cet ensemble de limitation de capacité est hérité par tous les processus créés sur le système.
VOIR AUSSI¶
capsh(1), setpriv(1), prctl(2), setfsuid(2), cap_clear(3), cap_copy_ext(3), cap_from_text(3), cap_get_file(3), cap_get_proc(3), cap_init(3), capgetp(3), capsetp(3), libcap(3), proc(5), credentials(7), pthreads(7), user_namespaces(7), captest(8), filecap(8), getcap(8), getpcaps(8), netcap(8), pscap(8), setcap(8)
include/linux/capability.h dans les sources du noyau Linux
TRADUCTION¶
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.
2 mai 2024 | Pages du manuel de Linux 6.8 |