Fuzzer for Linux Kernel Drivers

Overview

difuze: Fuzzer for Linux Kernel Drivers

License

This repo contains all the sources (including setup scripts), you need to get difuze up and running.

Tested on

Ubuntu >= 14.04.5 LTS

0. Running difuze from Docker

Refer the readme

As explained in our paper, There are two main components of difuze: Interface Recovery and Fuzzing Engine

1. Interface Recovery

The Interface recovery mechanism is based on LLVM analysis passes. Every step of interface recovery are written as individual passes. Follow the below instructions on how to get the Interface Recovery up and running.

1.1 Setup

This step takes care of installing LLVM and c2xml:

First, make sure that you have libxml (required for c2xml):

sudo apt-get install libxml2-dev
sudo pip install lxml

Next, We have created a single script, which downloads and builds all the required tools.

cd helper_scripts
python setup_difuze.py --help
usage: setup_difuze.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.

Example:

python setup_difuze.py -o difuze_deps

To complete the setup you also need modifications to your local PATH environment variable. The setup script will give you exact changes you need to do.

1.2 Building

This depends on the successful completion of Setup. We have a single script that builds everything, you are welcome.

cd InterfaceHandlers
./build.sh

1.3 Running

This depends on the successful completion of Build. To run the Interface Recovery components on kernel drivers, we need to first the drivers into llvm bitcode.

1.3.1 Building kernel

First, we need to have a buildable kernel. Which means you should be able to compile the kernel using regular build setup. i.e., make. We first capture the output of make command, from this output we extract the exact compilation command.

1.3.1.1 Generating output of make
Option 1: Using Bear (RECOMMENDED)
  1. Install Bear
  2. Run make using Bear:
    bear make <all the options to make>
    
    Example: bear make -j8

This will generate a file compile_commands.json in the current directory.

Option 2

Just pass V=1 and redirect the output to the file. Example:

make V=1 O=out ARCH=arm64 > makeout.txt 2>&1

NOTE: DO NOT USE MULTIPLE PROCESSES i.e., -j. Running in multi-processing mode will mess up the output file as multiple process try to write to the output file.

That's it. Next, in the following step our script takes the generated makeout.txt and run the Interface Recovery on all the recognized drivers.

1.3.2 Running Interface Recovery analysis

All the various steps of Interface Recovery are wrapped in a single script helper_scripts/run_all.py How to run:

cd helper_scripts
python run_all.py --help

usage: run_all.py [-h] [-l LLVM_BC_OUT] [-a CHIPSET_NUM] [-m MAKEOUT]
                  [-c COMPJSON] [-g COMPILER_NAME] [-n ARCH_NUM] [-o OUT]
                  [-k KERNEL_SRC_DIR] [-isclang] [-clangp CLANG_PATH]
                  [-llvmlinkp LLVMLINK_PATH] [-skb] [-skl] [-skp] [-skP]
                  [-ske] [-skI] [-ski] [-skv] [-skd] [-f IOCTL_FINDER_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.
  -c COMPJSON           Path to the compile_commands_json generated by Bear.
  -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.
  -k KERNEL_SRC_DIR     Base directory of the kernel sources.
  -isclang              flag to indicate that clang was used to built the
                        kernel
  -clangp CLANG_PATH    Absolute path to the clang binary (if not provided,
                        the one available in the path will be used)
  -llvmlinkp LLVMLINK_PATH
                        Absolute path to the llvm-link binary (if not
                        provided, the one available in the path will be used)
  -skb                  Skip LLVM Build (default: not skipped).
  -skl                  Skip Dr Linker (default: not skipped).
  -skp                  Skip Parsing Headers (default: not skipped).
  -skP                  Skip Generating Preprocessed files (default: not
                        skipped).
  -ske                  Skip Entry point identification (default: not
                        skipped).
  -skI                  Skip Generate Includes (default: not skipped).
  -ski                  Skip IoctlCmdParser run (default: not skipped).
  -skv                  Skip V4L2 ioctl processing (default: not skipped).
  -skd                  Skip Device name finder (default: not skipped).
  -f IOCTL_FINDER_OUT   Path to the output folder where the ioctl command
                        finder output should be stored.


The script builds, links and runs Interface Recovery on all the recognized drivers, as such it might take considerable time(45 min-90 min).

The above script performs following tasks in a multiprocessor mode to make use of all CPU cores:

1.3.2.1 LLVM Build
  • Enabled by default.

All the bitcode files generated will be placed in the folder provided to the argument -l. This step takes considerable time, depending on the number of cores you have. So, if you had already done this step, You can skip this step by passing -skb.

1.3.2.2 Linking all driver bitcode files in s consolidated bitcode file.
  • Enabled by default

This performs linking, it goes through all the bitcode files and identifies the related bitcode files that need to be linked and links them (using llvm-link) in to a consolidated bitcode file (which will be stored along side corresponding bitcode file).

Similar to the above step, you can skip this step by passing -skl.

1.3.2.3 Parsing headers to identify entry function fields.
  • Enabled by default.

This step looks for the entry point declarations in the header files and stores their configuration in the file: hdr_file_config.txt under LLVM build directory.

To skip: -skp

1.3.2.4 Identify entry points in all the consolidated bitcode files.
  • Enabled by default

This step identifies all the entry points across all the driver consolidated bitcode files. The output will be stored in file: entry_point_out.txt under LLVM build directory.

Example of contents in the file entry_point_out.txt:

IOCTL:msm_lsm_ioctl:/home/difuze/kernels/pixel/msm/sound/soc/msm/qdsp6v2/msm-lsm-client.c:msm_lsm_ioctl.txt:/home/difuze/pixel/llvm_out/sound/soc/msm/qdsp6v2/llvm_link_final/final_to_check.bc
IOCTL:msm_pcm_ioctl:/home/difuze/kernels/pixel/msm/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c:msm_pcm_ioctl.txt:/home/difuze/pixel/llvm_out/sound/soc/msm/qdsp6v2/llvm_link_final/final_to_check.bc

To skip: -ske

1.3.2.5 Run Ioctl Cmd Finder on all the identified entry points.
  • Enabled by default.

This step will run the main Interface Recovery component (IoctlCmdParser) on all the entry points in the file entry_point_out.txt. The output for each entry point will be stored in the folder provided for option -f.

To skip: -ski

1.4 Example:

Now, we will show an example from the point where you have kernel sources to the point of getting Interface Recovery results.

We have uploaded a mediatek kernel 33.2.A.3.123.tar.bz2. First download and extract the above file.

Lets say you extracted the above file in a folder called: ~/mediatek_kernel

1.4.1 Building

Install Bear and follow the below steps:

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
# generating compile_commands.json
bear make -j8 O=out ARCH=arm64

1.4.2 Running Interface Recovery

cd <repo_path>/helper_scripts

python run_all.py -l ~/mediatek_kernel/llvm_bitcode_out -a 1 -c ~/mediatek_kernel/kernel-3.18/compile_commands.json -n 2 -o ~/mediatek_kernel/kernel-3.18/out -k ~/mediatek_kernel/kernel-3.18 -f ~/mediatek_kernel/ioctl_finder_out

The above command takes quite some time (30 min - 1hr).

1.4.3 Understanding the output

First, all the analysis results will be in the folder: ~/mediatek_kernel/ioctl_finder_out (argument given to the option -f), for each entry point a .txt file will be created, which contains all the information about the recovered interface.

If you are interested in information about just the interface and don't care about anything else, We recommend you use the parse_interface_output.py script. This script converts the crazy output of Interface Recovery pass into nice json files with a clean and consistent format.

cd <repo_path>/helper_scripts
python parse_interface_output.py <ioctl_finder_out_dir> <output_directory_for_json_files>

Here <ioctl_finder_out_dir> should be same as the folder you provided to the -f option and <output_directory_for_json_files> is the folder where the json files should be created.

You can use the corresponding json files for the interface recovery of the corresponding ioctl.

1.4.4 Things to note:

1.4.4.1 Value for option -g (only if you use makeout.txt)

To provide value for option -g you need to know the name of the *-gcc binary used to compile the kernel. An easy way to know this would be to grep for gcc in makeout.txt and you will see compiler commands from which you can know the *-gcc binary name.

For our example above, if you do grep gcc makeout.txt for the example build, you will see lot of lines like below:

aarch64-linux-android-gcc -Wp,-MD,fs/jbd2/.transaction.o.d  -nostdinc -isystem ...

So, the value for -g should be aarch64-linux-android-gcc.

If the kernel to be built is 32-bit then the binary most likely will be arm-eabi-gcc

For Qualcomm (or msm) chipsets, you may see *gcc-wrapper.py instead of *.gcc, in which case you should provide the *gcc-wrapper.py.

1.4.4.2 Value for option -a

Depeding on the chipset type, you need to provide corresponding number.

1.4.4.3 Value for option -o

This is the path of the folder provided to the option O= for make command during kernel build.

Not all kernels need a separate out path. You may build kernel by not providing an option O, in which case you SHOULD NOT provide value for that option while running run_all.py.

Kernels built using clang

For kernels built using clang, in addition to the above options please specify the following options (assuming you used compile_commands.json):

-isclang -clangp <PATH_TO_THE_CLANG_USED_TO_BUILD_THE_KERNEL> -llvmlinkp <PATH_TO_THE_LLVM_LINK (will be in the same folder as clang)>

1.5 Post Processing

Before we can begin fuzzing we need to process the output a bit with our very much research quality (sorry) parsers.

These are found here. The main script to run will be run_all.py:

$ python run_all.py --help
usage: run_all.py [-h] -f F -o O [-n {manual,auto,hybrid}] [-m M]

run_all options

optional arguments:
  -h, --help            show this help message and exit
  -f F                  Filename of the ioctl analysis output OR the entire
                        output directory created by the system
  -o O                  Output directory to store the results. If this
                        directory does not exist it will be created
  -n {manual,auto,hybrid}
                        Specify devname options. You can choose manual
                        (specify every name manually), auto (skip anything that
                        we don't identify a name for), or hybrid (if we
                        detected a name, we use it, else we ask the user)
  -m M                  Enable multi-device output most ioctls only have one
                        applicable device node, but some may have multiple. (0
                        to disable)

You'll want to pass -f the output directory of the ioctl analysis e.g. ~/mediatek_kernel/ioctl_finder_out.

-o Is where you where to store the post-processed results. These will be easily digestible XML files (jpits).

-n Specifies the system to what degree you want to rely on our device name recovery. If you don't want to do any work/name hunting, you can specify auto. This of course comes at the cost of skipping any device for which we don't recover a name. If you want to be paranoid and not trust any of our recovery efforts (totally reasonable) you can use the manual option to name every single device yourself. hybrid then is a combination of both -- we will name the device for you when we can, and fall back to you when we've failed.

-m Sometimes ioctls can correspond to more than one device (this is common with v4l2/subdev ioctls for example). Support for this in enabled by default, but it requires user interaction to specify the numberof devices for each device. If this is too annoying for you, you can disable the prompt by passing -m 0 (we will assume a single device for each ioctl).

After running, you should have, in your out folder, a folder for each ioctl.

2 Fuzzing

2.1 Mango Fuzz

MangoFuzz is our simple prototype fuzzer and is based off of Peach (specifically MozPeach).

It's not a particularly sophisticated fuzzer but it does find bugs. It was also built to be easily expandable. There are 2 components to this fuzzer, the fuzz engine and the executor. The executor can be found here, and the fuzz engine can be found here.

2.1.1 Executor

The executor runs on the phone, listening for data that the fuzz engine will send to it.

Simply compile it for your phones architecture, adb push it on to the phone, and execute with the port you want it to listen on!

2.1.2 Fuzz Engine

Interfacing with MangoFuzz is fairly simple. You'll want an Engine object and a Parser object, which you'll feed your engine into. From here, you parse jpits with your Parser, and then run the Engine. Easy! We've provided some simple run scripts to get you started.

To run against specific drivers you can use runner.py on one of the ioctl folders in the output directory (created by our post processing scripts).

e.g. ./runner.py -f honor8/out/chb -num 1000. This tells MangoFuzz to run for 1000 iterations against all ioctl command value pairs pertaining to the chb ioctl/driver.

If instead we want to run against an entire device (phone), you can use dev_runner.py. e.g. ./dev_runner.py -f honor8/out -num 100. This will continue looping over the driver files, randomly switching between them for 100 iterations each.

Note that before the fuzz engine can communicate with the phone, you'll need to use ADB to set up port forwarding e.g. adb forward tcp:2022 tcp:2022

Owner
seclab
The Computer Security Group at UC Santa Barbara
seclab
Similarity-based Gray-box Adversarial Attack Against Deep Face Recognition

Similarity-based Gray-box Adversarial Attack Against Deep Face Recognition Introduction Run attack: SGADV.py Objective function: foolbox/attacks/gradi

1 Jul 18, 2022
Reverse engineering recurrent neural networks with Jacobian switching linear dynamical systems

Reverse engineering recurrent neural networks with Jacobian switching linear dynamical systems This repository is the official implementation of Rever

6 Aug 25, 2022
Official Pytorch implementation of "Beyond Static Features for Temporally Consistent 3D Human Pose and Shape from a Video", CVPR 2021

TCMR: Beyond Static Features for Temporally Consistent 3D Human Pose and Shape from a Video Qualtitative result Paper teaser video Introduction This r

Hongsuk Choi 215 Jan 06, 2023
An efficient implementation of GPNN

Efficient-GPNN An efficient implementation of GPNN as depicted in "Drop the GAN: In Defense of Patches Nearest Neighbors as Single Image Generative Mo

7 Apr 16, 2022
Image marine sea litter prediction Shiny

MARLITE Shiny app for floating marine litter detection in aerial images. This directory contains the instructions and software needed to install the S

19 Dec 22, 2022
Official implementation of "UCTransNet: Rethinking the Skip Connections in U-Net from a Channel-wise Perspective with Transformer"

[AAAI2022] UCTransNet This repo is the official implementation of "UCTransNet: Rethinking the Skip Connections in U-Net from a Channel-wise Perspectiv

Haonan Wang 199 Jan 03, 2023
HPRNet: Hierarchical Point Regression for Whole-Body Human Pose Estimation

HPRNet: Hierarchical Point Regression for Whole-Body Human Pose Estimation Official PyTroch implementation of HPRNet. HPRNet: Hierarchical Point Regre

Nermin Samet 53 Dec 04, 2022
Meta-Learning Sparse Implicit Neural Representations (NeurIPS 2021)

Meta-SparseINR Official PyTorch implementation of "Meta-learning Sparse Implicit Neural Representations" (NeurIPS 2021) by Jaeho Lee*, Jihoon Tack*, N

Jaeho Lee 41 Nov 10, 2022
PyTorch code for SENTRY: Selective Entropy Optimization via Committee Consistency for Unsupervised DA

PyTorch Code for SENTRY: Selective Entropy Optimization via Committee Consistency for Unsupervised Domain Adaptation Viraj Prabhu, Shivam Khare, Deeks

Viraj Prabhu 46 Dec 24, 2022
Personal project about genus-0 meshes, spherical harmonics and a cow

How to transform a cow into spherical harmonics ? Spot the cow, from Keenan Crane's blog Context In the field of Deep Learning, training on images or

3 Aug 22, 2022
Code repository for Self-supervised Structure-sensitive Learning, CVPR'17

Self-supervised Structure-sensitive Learning (SSL) Ke Gong, Xiaodan Liang, Xiaohui Shen, Liang Lin, "Look into Person: Self-supervised Structure-sensi

Clay Gong 219 Dec 29, 2022
A framework for the elicitation, specification, formalization and understanding of requirements.

A framework for the elicitation, specification, formalization and understanding of requirements.

NASA - Software V&V 161 Jan 03, 2023
以孤立语假设和宽度优先搜索为基础,构建了一种多通道堆叠注意力Transformer结构的斗地主ai

ddz-ai 介绍 斗地主是一种扑克游戏。游戏最少由3个玩家进行,用一副54张牌(连鬼牌),其中一方为地主,其余两家为另一方,双方对战,先出完牌的一方获胜。 ddz-ai以孤立语假设和宽度优先搜索为基础,构建了一种多通道堆叠注意力Transformer结构的系统,使其经过大量训练后,能在实际游戏中获

freefuiiismyname 88 May 15, 2022
LieTransformer: Equivariant Self-Attention for Lie Groups

LieTransformer This repository contains the implementation of the LieTransformer used for experiments in the paper LieTransformer: Equivariant Self-At

OxCSML (Oxford Computational Statistics and Machine Learning) 50 Dec 28, 2022
Code base for "On-the-Fly Test-time Adaptation for Medical Image Segmentation"

On-the-Fly Adaptation Official Pytorch Code base for On-the-Fly Test-time Adaptation for Medical Image Segmentation Paper Introduction One major probl

Jeya Maria Jose 17 Nov 10, 2022
Improving Query Representations for DenseRetrieval with Pseudo Relevance Feedback:A Reproducibility Study.

APR The repo for the paper Improving Query Representations for DenseRetrieval with Pseudo Relevance Feedback:A Reproducibility Study. Environment setu

ielab 8 Nov 26, 2022
Refactoring dalle-pytorch and taming-transformers for TPU VM

Text-to-Image Translation (DALL-E) for TPU in Pytorch Refactoring Taming Transformers and DALLE-pytorch for TPU VM with Pytorch Lightning Requirements

Kim, Taehoon 61 Nov 07, 2022
[CVPR 2021] Scan2Cap: Context-aware Dense Captioning in RGB-D Scans

Scan2Cap: Context-aware Dense Captioning in RGB-D Scans Introduction We introduce the task of dense captioning in 3D scans from commodity RGB-D sensor

Dave Z. Chen 79 Nov 07, 2022
[CVPR'21] Locally Aware Piecewise Transformation Fields for 3D Human Mesh Registration

Locally Aware Piecewise Transformation Fields for 3D Human Mesh Registration This repository contains the implementation of our paper Locally Aware Pi

sfwang 70 Dec 19, 2022
Adaptive, interpretable wavelets across domains (NeurIPS 2021)

Adaptive wavelets Wavelets which adapt given data (and optionally a pre-trained model). This yields models which are faster, more compressible, and mo

Yu Group 50 Dec 16, 2022