
DR.CHECKER : Un outil fiable de détection de vulnérabilités pour les pilotes du noyau Linux

Ce dépôt contient toutes les sources, y compris les scripts d'installation. Maintenant avec une interface utilisateur étonnante pour visualiser les avertissements ainsi que les fichiers source correspondants.
Ubuntu >= 14.04.5 LTS
16 février 2018 :
Reportez-vous au document Utilisation de Docker pour plus de détails sur l'utilisation de DR.CHECKER dans un conteneur docker pré-construit.
Notre implémentation est basée sur LLVM, plus précisément LLVM 3.8. Nous avons également besoin d'outils comme c2xml pour analyser les en-têtes.
Tout d'abord, assurez-vous d'avoir cmake (utilisé par les scripts de configuration/construction) et libxml (requis pour c2xml) :
sudo apt-get install cmake libxml2-dev
Ensuite, nous avons créé un script unique qui télécharge et construit tous les outils nécessaires.
cd helper_scripts
python setup_drchecker.py --help
usage: setup_drchecker.py [-h] [-b TARGET_BRANCH] [-o OUTPUT_FOLDER]
optional arguments:
-h, --help show this help message and exit
-b TARGET_BRANCH Branch (i.e. version) of the LLVM to setup. Default:
release_38 e.g., release_38
-o OUTPUT_FOLDER Folder where everything needs to be setup.
Exemple :
python setup_drchecker.py -o drchecker_deps
Pour terminer la configuration, vous devez également modifier votre variable d'environnement PATH locale. Le script de configuration vous donnera les modifications exactes à apporter.
Cette étape dépend de la réussite de la Configuration. Nous avons un seul script qui construit tout, vous êtes les bienvenus.
cd llvm_analysis
./build.sh
Cette étape dépend de la réussite de la Construction. Pour exécuter DR.CHECKER sur les pilotes du noyau, nous devons d'abord les convertir en bitcode llvm.
Tout d'abord, nous devons avoir un noyau constructible. Cela signifie que vous devez être capable de compiler le noyau en utilisant la configuration de construction habituelle, c'est-à-dire make.
Nous capturons d'abord la sortie de la commande make, et à partir de cette sortie nous extrayons la commande de compilation exacte.
make (ou makeout.txt)Passez simplement V=1 et redirigez la sortie vers le fichier.
Exemple :
make V=1 O=out ARCH=arm64 > makeout.txt 2>&1
REMARQUE : N'UTILISEZ PAS DE PROCESSUS MULTIPLES, c'est-à-dire -j. L'exécution en mode multi-processus perturbera le fichier de sortie car plusieurs processus tentent d'écrire dans le fichier de sortie.
Voilà. DR.CHECKER s'occupe du reste.
Il y a plusieurs étapes pour exécuter l'analyse DR.CHECKER, toutes ces étapes sont regroupées dans un seul script helper_scripts/runner_scripts/run_all.py
Comment exécuter :
python run_all.py --help
usage: run_all.py [-h] [-l LLVM_BC_OUT] [-a CHIPSET_NUM] [-m MAKEOUT] [-g COMPILER_NAME] [-n ARCH_NUM] [-o OUT] [-k KERNEL_SRC_DIR] [-skb] [-skl] [-skp] [-ske] [-ski] [-f SOUNDY_ANALYSIS_OUT]
optional arguments:
-h, --help show this help message and exit
-l LLVM_BC_OUT Destination directory where all the generated bitcode files should be stored.
-a CHIPSET_NUM Chipset number. Valid chipset numbers are:
1(mediatek)|2(qualcomm)|3(huawei)|4(samsung)
-m MAKEOUT Path to the makeout.txt file.
-g COMPILER_NAME Name of the compiler used in the makeout.txt, This is
needed to filter out compilation commands. Ex: aarch64-linux-android-gcc
-n ARCH_NUM Destination architecture, 32 bit (1) or 64 bit (2).
-o OUT Path to the out folder. This is the folder, which
could be used as output directory during compiling
some kernels. (Note: Not all kernels needs a separate out folder)
-k KERNEL_SRC_DIR Base directory of the kernel sources.
-skb Skip LLVM Build (default: not skipped).
-skl Skip Dr Linker (default: not skipped).
-skp Skip Parsing Headers (default: not skipped).
-ske Skip Entry point identification (default: not
skipped).
-ski Skip Soundy Analysis (default: not skipped).
-f SOUNDY_ANALYSIS_OUT Path to the output folder where the soundy analysis output should be stored.
Le script construit, lie et exécute DR.CHECKER sur tous les pilotes, ce qui peut prendre un temps considérable (45 min - 90 min). Si vous souhaitez exécuter DR.CHECKER manuellement sur des pilotes individuels, référez-vous à standalone
Le script ci-dessus effectue les tâches suivantes en mode multiprocesseur pour utiliser tous les cœurs du CPU :
Tous les fichiers bitcode générés seront placés dans le dossier fourni à l'argument -l.
Cette étape prend un temps considérable, selon le nombre de cœurs dont vous disposez.
Donc, si vous avez déjà effectué cette étape, vous pouvez la sauter en passant -skb.
Cette opération effectue la liaison, elle parcourt tous les fichiers bitcode et identifie les fichiers bitcode associés qui doivent être liés et les lie (en utilisant llvm-link) en un fichier bitcode consolidé (qui sera stocké à côté du fichier bitcode correspondant).
Comme pour l'étape précédente, vous pouvez sauter cette étape en passant -skl.
Cette étape recherche les déclarations de points d'entrée dans les fichiers d'en-tête et stocke leur configuration dans le fichier : hdr_file_config.txt dans le répertoire de construction LLVM.
Pour sauter : -skp
Cette étape identifie tous les points d'entrée dans tous les fichiers bitcode consolidés des pilotes.
La sortie sera stockée dans le fichier : entry_point_out.txt dans le répertoire de construction LLVM.
Exemple de contenu du fichier entry_point_out.txt :
FileRead:hidraw_read:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
FileWrite:hidraw_write:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
IOCTL:hidraw_ioctl:/home/drchecker/33.2.A.3.123/llvm_bc_out/drivers/hid/llvm_link_final/final_to_check.bc
Pour sauter : -ske
Cette étape exécutera DR.CHECKER sur tous les points d'entrée du fichier entry_point_out.txt. La sortie pour chaque point d'entrée sera stockée dans le dossier fourni pour l'option -f.
Pour sauter : -ski
Maintenant, nous allons montrer un exemple du moment où vous avez les sources du noyau jusqu'à l'obtention des avertissements de vulnérabilité.
Nous avons mis en ligne un noyau mediatek 33.2.A.3.123.tar.bz2. Téléchargez d'abord et extrayez le fichier ci-dessus.
Disons que vous avez extrait le fichier ci-dessus dans un dossier appelé : ~/mediatek_kernel
cd ~/mediatek_kernel
source ./env.sh
cd kernel-3.18
# the following step may not be needed depending on the kernel
mkdir out
make O=out ARCH=arm64 tubads_defconfig
# this following command copies all the compilation commands to makeout.txt
make V=1 -j8 O=out ARCH=arm64 > makeout.txt 2>&1
cd <repo_path>/helper_scripts/runner_scripts
python run_all.py -l ~/mediatek_kernel/llvm_bitcode_out -a 1 -m ~/mediatek_kernel/kernel-3.18/makeout.txt -g aarch64-linux-android-gcc -n 2 -o ~/mediatek_kernel/kernel-3.18/out -k ~/mediatek_kernel/kernel-3.18 -f ~/mediatek_kernel/dr_checker_out
La commande ci-dessus prend un certain temps (30 min - 1 h).
Tout d'abord, tous les résultats de l'analyse se trouveront dans le dossier : ~/mediatek_kernel/dr_checker_out (argument donné à l'option -f), pour chaque point d'entrée un fichier .json sera créé contenant tous les avertissements au format JSON. Ces fichiers json contiennent des avertissements organisés par contextes.
Deuxièmement, le dossier ~/mediatek_kernel/dr_checker_out/instr_warnings (par rapport à l'argument donné à l'option -f) contient des avertissements organisés par emplacement d'instruction.
Ces avertissements peuvent être analysés à l'aide de notre Visualiseur.
Enfin, un résumé de tous les avertissements pour chaque point d'entrée organisé par type sera écrit dans le fichier CSV de sortie : ~/mediatek_kernel/dr_checker_out/warnings_stats.csv (par rapport à l'argument donné à l'option -f).
-gPour fournir une valeur pour l'option -g, vous devez connaître le nom du binaire *-gcc utilisé pour compiler le noyau.
Un moyen simple de le savoir serait de grep gcc dans makeout.txt et vous verrez des commandes de compilateur à partir desquelles vous pouvez connaître le nom du binaire *-gcc.
Pour notre exemple ci-dessus, si vous faites grep gcc makeout.txt pour la construction exemple, vous verrez beaucoup de lignes comme ci-dessous :
aarch64-linux-android-gcc -Wp,-MD,fs/jbd2/.transaction.o.d -nostdinc -isystem ...
Donc, la valeur pour -g doit être aarch64-linux-android-gcc.
Si le noyau à construire est en 32 bits, alors le binaire sera très probablement arm-eabi-gcc
-aSelon le type de chipset, vous devez fournir le numéro correspondant.
-oC'est le chemin du dossier fourni à l'option O= pour la commande make lors de la construction du noyau.
Tous les noyaux n'ont pas besoin d'un chemin de sortie séparé. Vous pouvez construire le noyau sans fournir d'option O, auquel cas vous NE DEVEZ PAS fournir de valeur pour cette option lors de l'exécution de run_all.py.
Nous fournissons une interface utilisateur Web pour visualiser tous les avertissements. Veuillez vous référer à Visualisation.
Vous pouvez désactiver un ou plusieurs vérificateurs de vulnérabilité en décommentant les lignes #define DISABLE_* correspondantes dans BugDetectorDriver.cpp
Selon vos goûts, nous fournissons également un script pour post-traiter les résultats. Jetez-y un coup d'œil.
Amusez-vous bien !!