Contrôle d’accès
Comme mentionné précédemment, perf
permet d’obtenir des informations
extrêmement détaillés sur l’activité système, ce qui représente un risque de
sécurité sur une machine avec plusieurs utilisateurs. Pour éviter tout accident,
la plupart des distributions Linux limitent donc l’utilisation d’au moins une
partie des fonctionnalités de perf
au superutilisateur root
par défaut.
Voici une liste (probablement non exhaustive) de verrous de sécurité qui sont installés par défaut sur les distributions Linux courantes, et de procédures pour les désactiver si nécessaire.
perf_event_paranoid
L’utilisation de base de perf
est contrôlée par le réglage
perf_event_paranoid
du noyau. Ce réglage peut être modifié temporairement en
utilisant la commande sysctl kernel.perf_event_paranoid=x
, ou de façon
permanente en écrivant kernel.perf_event_paranoid=x
dans un fichier du
répertoire /etc/sysctl.d
.
Les valeurs possibles de ce réglage sont :
- 3 : Les utilisateurs non privilégiés ne peuvent pas utiliser perf du tout (réglage par défaut sous Debian, Ubuntu et Android).
- 2 : Les utilisateurs non privilégiés ne peuvent suivre que des processus individuels, et seulement durant l’exécution en mode utilisateur (pas de suivi de l’activité noyau déclenchée par le processus).
- 1 : L’utilisation de perf est toujours restreinte au suivi de processus individuels, mais le suivi de l’activité noyau directement associée au processus (appels système synchrones) est possible.
- 0 : Certaines formes de suivi de l’activité du système entier deviennent possible (ex : suivi des compteurs de performance CPU), mais le suivi à grain fin de l’activité système via les mécanismes de tracing du noyau demeure inaccessible aux utilisateurs non privilégiés.
- -1 : Aucune restriction n’est appliquée au niveau de l’outil
perf
(même si des contrôles d’accès peuvent encore s’appliquer en aval de l’outil, on va le voir plus loin).
Les noyaux récents devraient fournir un
contrôle d’accès à grain plus fin
basé sur les capabilities, permettant par exemple de ne donner accès à perf
qu’à un certain groupe d’utilisateurs. Mais mon dernier test sous Linux 5.14
n’était pas concluant, il fallait encore avoir perf_event_paranoid=-1
pour un
accès complet à perf
.
kptr_restrict
Pour interpréter un profil l’activité CPU du noyau, il est nécessaire de savoir
à quelle partie du noyau on a affaire. perf
mesure la position du pointeur
d’instruction du noyau, mais pour traduire cette information bas niveau en
information symbolique de haut niveau (nom de fonction), il a besoin de
connaître la position en mémoire des différents symboles du noyau.
Cette information est malheureusement également très utile pour mener une
attaque contre le noyau Linux, et elle n’est donc accessible qu’à root
par
défaut. Pour la rendre accessible à tous les utilisateurs, il faut mettre à
0 le réglage kptr_restrict
du noyau.
Là encore, on peut le faire de façon temporaire avec la commande
sysctl kernel.kptr_restrict=0
, ou de façon permanente en écrivant
kernel.kptr_restrict=0
dans un fichier du répertoire /etc/sysctl.d
.
Et là encore, il devrait y avoir moyen de gérer ce contrôle d’accès avec la
capability CAP_SYSLOG
, mais cela ne semble pas fonctionner sous Linux 5.14.
Tracing
Le suivi à grain fin de l’activité noyau (tracing) est une fonctionalité du noyau Linux qui est particulièrement puissante pour l’analyse de performances, mais aussi particulièrement dangereuse sur un système multi-utilisateurs :
- Elle donne trivialement accès à l’ensemble des données passées en paramètres ou reçues en résultat d’appels système par les applications, ce qui peut inclure toutes sortes d’informations secrètes : mots de passe, clés SSH…
- Il est relativement facile de charger fortement le système en l’utilisant, soit en créant une récursion infinie (suivi d’un évènement qui survient lorsqu’on suit un événement), soit en suivant de façon exhaustive un évènement extrêmement fréquent (ex : basculement entre deux tâches).
Cette fonctionnalité dispose donc de ses propres mécanismes de sécurité en sus
de la protection perf_event_paranoid
susmentionnée. Si vous souhaitez la
rendre accessible à un groupe d’utilisateurs, disons le groupe perf
, vous
devez…
- Remonter les pseudo-systèmes de fichier
/sys/kernel/debug/tracing
et/sys/kernel/tracing
avec des permissions 770 (u+rwx g+rwx). - Remonter le pseudo-système de fichier
/sys/kernel/debug
avec les permissions 750 (u+rwx g+rx) pour permettre la navigation jusqu’à/sys/kernel/debug/tracing
. - Transférer la propriété de
/sys/kernel/debug
et/sys/kernel/tracing
au groupeperf
. - Ajuster les permissions des fichiers de
/sys/kernel/debug/tracing
pour faire en sorte que tout ce qui est inscriptible par l’utilisateur l’est par le groupe.
Voici un service systemd permettant d’effectuer ces modifications à chaque démarrage :
[Unit]
Description=Let perf group use ftrace, kprobes and uprobes
RequiresMountsFor=/sys/kernel/tracing
RequiresMountsFor=/sys/kernel/debug/tracing
Before=multi-user.target
[Install]
WantedBy=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=yes
Restart=no
ExecStart=bash -c 'mount -o remount,mode=770 /sys/kernel/tracing && mount -o remount,mode=750 /sys/kernel/debug && mount -o remount,mode=770 /sys/kernel/debug/tracing && chown -R root:perf /sys/kernel/tracing /sys/kernel/debug/tracing && find /sys/kernel/debug/tracing/ -perm -u=w -exec chmod g+w \'{}\' \\+'
ExecStop=bash -c 'mount -o remount,mode=700 /sys/kernel/tracing && mount -o remount,mode=700 /sys/kernel/debug/tracing && mount -o remount,mode=700 /sys/kernel/debug && chown -R root:root /sys/kernel/tracing /sys/kernel/debug'
Si vous utilisez perf probe
, sachez que cette commande peut remettre certains
des fichiers virtuels sous le contrôle de root:root
et que vous serez amené à
refaire des chown
pour rétablir les permissions voulues, comme dans les
exemples “administrateur” de la section perf probe
de ce TP.