
DR.CHECKER : Una herramienta sólida de detección de vulnerabilidades para controladores del kernel de Linux

Este repositorio contiene todas las fuentes, incluidos los scripts de configuración. Ahora con una increíble interfaz de usuario para ver las advertencias junto con los archivos fuente correspondientes.
Ubuntu >= 14.04.5 LTS
16 de febrero de 2018:
Consulte el documento Uso de Docker para obtener detalles sobre cómo usar DR.CHECKER en un contenedor docker preconstruido.
Nuestra implementación se basa en LLVM, específicamente LLVM 3.8. También necesitamos herramientas como c2xml para analizar los encabezados.
Primero, asegúrese de tener cmake (usado por los scripts de configuración/compilación) y libxml (requerido para c2xml):
sudo apt-get install cmake libxml2-dev
A continuación, hemos creado un único script que descarga y compila todas las herramientas necesarias.
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.
Ejemplo:
python setup_drchecker.py -o drchecker_deps
Para completar la configuración, también necesita modificaciones en su variable de entorno PATH. El script de configuración le dará los cambios exactos que necesita realizar.
Esto depende de la finalización exitosa de Configuración. Tenemos un solo script que compila todo, de nada.
cd llvm_analysis
./build.sh
Esto depende de la finalización exitosa de Compilación. Para ejecutar DR.CHECKER en controladores del kernel, primero debemos convertirlos a bitcode de LLVM.
Primero, necesitamos tener un kernel compilable. Lo que significa que debería poder compilar el kernel usando la configuración de compilación habitual, es decir, make.
Primero capturamos la salida del comando make, de esta salida extraemos el comando de compilación exacto.
make (o makeout.txt)Simplemente pase V=1 y redirija la salida al archivo.
Ejemplo:
make V=1 O=out ARCH=arm64 > makeout.txt 2>&1
NOTA: NO USE MÚLTIPLES PROCESOS, es decir, -j. Ejecutar en modo multiproceso desordenará el archivo de salida ya que múltiples procesos intentan escribir en él.
Eso es todo. DR.CHECKER se encargará del resto.
Hay varios pasos para ejecutar el análisis de DR.CHECKER, todos estos pasos están envueltos en un único script helper_scripts/runner_scripts/run_all.py
Cómo ejecutar:
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.
El script compila, enlaza y ejecuta DR.CHECKER en todos los controladores, por lo que puede llevar un tiempo considerable (45 min-90 min). Si desea ejecutar DR.CHECKER manualmente en controladores individuales, consulte independiente
El script anterior realiza las siguientes tareas en modo multiprocesador para aprovechar todos los núcleos de la CPU:
Todos los archivos de bitcode generados se colocarán en la carpeta proporcionada al argumento -l.
Este paso lleva un tiempo considerable, dependiendo del número de núcleos que tenga.
Por lo tanto, si ya ha realizado este paso, puede omitirlo pasando -skb.
Esto realiza el enlace, recorre todos los archivos de bitcode e identifica los archivos de bitcode relacionados que necesitan ser enlazados y los enlaza (usando llvm-link) en un archivo de bitcode consolidado (que se almacenará junto al archivo de bitcode correspondiente).
Similar al paso anterior, puede omitir este paso pasando -skl.
Este paso busca las declaraciones de puntos de entrada en los archivos de encabezado y almacena su configuración en el archivo: hdr_file_config.txt en el directorio de compilación de LLVM.
Para omitir: -skp
Este paso identifica todos los puntos de entrada en todos los archivos de bitcode consolidados de controladores.
La salida se almacenará en el archivo: entry_point_out.txt en el directorio de compilación de LLVM.
Ejemplo de contenido del archivo 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
Para omitir: -ske
Este paso ejecutará DR.CHECKER en todos los puntos de entrada del archivo entry_point_out.txt. La salida para cada punto de entrada se almacenará en la carpeta proporcionada para la opción -f.
Para omitir: -ski
Ahora, mostraremos un ejemplo desde el punto donde tiene las fuentes del kernel hasta el punto de obtener advertencias de vulnerabilidad.
Hemos subido un kernel mediatek 33.2.A.3.123.tar.bz2. Primero descargue y extraiga el archivo anterior.
Supongamos que extrajo el archivo anterior en una carpeta llamada: ~/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
El comando anterior lleva bastante tiempo (30 min - 1 hr).
Primero, todos los resultados del análisis estarán en la carpeta: ~/mediatek_kernel/dr_checker_out (argumento dado a la opción -f), para cada punto de entrada se creará un archivo .json que contiene todas las advertencias en formato JSON. Estos archivos json contienen advertencias organizadas por contextos.
Segundo, la carpeta ~/mediatek_kernel/dr_checker_out/instr_warnings (con respecto al argumento dado a la opción -f) contiene advertencias organizadas por ubicación de instrucción.
Estas advertencias pueden analizarse usando nuestro Visualizador.
Finalmente, un resumen de todas las advertencias para cada punto de entrada organizado por tipo se escribirá en el archivo CSV de salida: ~/mediatek_kernel/dr_checker_out/warnings_stats.csv (con respecto al argumento dado a la opción -f).
-gPara proporcionar el valor para la opción -g necesita conocer el nombre del binario *-gcc utilizado para compilar el kernel. Una forma fácil de saberlo sería hacer grep de gcc en makeout.txt y verá comandos del compilador de los cuales puede conocer el nombre del binario *-gcc.
Para nuestro ejemplo anterior, si hace grep gcc makeout.txt para la compilación de ejemplo, verá muchas líneas como la siguiente:
aarch64-linux-android-gcc -Wp,-MD,fs/jbd2/.transaction.o.d -nostdinc -isystem ...
Por lo tanto, el valor para -g debe ser aarch64-linux-android-gcc.
Si el kernel a compilar es de 32 bits, entonces el binario muy probablemente será arm-eabi-gcc
-aDependiendo del tipo de chipset, debe proporcionar el número correspondiente.
-oEsta es la ruta de la carpeta proporcionada a la opción O= para el comando make durante la compilación del kernel.
No todos los kernels necesitan una ruta de salida separada. Puede compilar el kernel sin proporcionar la opción O, en cuyo caso NO DEBE proporcionar un valor para esa opción al ejecutar run_all.py.
Proporcionamos una interfaz de usuario basada en web para ver todas las advertencias. Consulte Visualización.
Puede deshabilitar uno o más comprobadores de vulnerabilidad descomentando las líneas #define DISABLE_* correspondientes en BugDetectorDriver.cpp
A su gusto, también proporcionamos un script para posprocesar los resultados. Échale un vistazo.
¡¡Diviértete!!