sifter

Sifter

Sifter generates syscall tracers and filters for kernel modules automatically. It utilizes Syzkaller’s syscall description and generates an eBPF/tracepoints tracer that logs syscalls along with their arguments. After analyzing the trace, seccomp/eBPF filters are generated to limit untrusted programs’ syscall usage, which includes their argument values and the sequences. Currently, the prototype is implemented and tested on Google Pixel 3.

Device setup

To try Sifter on Google Pixel 8, you will need to compile and install the customized Android and kernel.

Installing AOSP

Download AOSP source

mkdir main && cd main && REPO_ALLOW_SHALLOW=0 repo init -c -u https://android.googlesource.com/platform/manifest -b main --use-superproject --partial-clone --partial-clone-exclude=platform/frameworks/base --clone-filter=blob:limit=100k && repo sync -c -j32

Patch AOSP to support tracers and filters generated by Sifter. The patch files can be found in sifter/patches-new/

cd bionic && git apply <sifter>/patches-new/sifter-bionic.patch && cd ../
cd external/libbpf && git apply <sifter>/patches-new/sifter-libbpf.patch && cd ../../
cd frameworks/base && git apply <sifter>/patches-new/sifter-frameworks.patch && cd ../
cd system/selinux && git apply <sifter>/patches-new/sifter-selinux.patch && cd ../

Compile AOSP

source build/envsetup.sh
lunch shiba-trunk_staging-userdebug
m

Enter recovery mode by pressing and holding power + volume down bottons and then flash the device

fastboot --disable-verity --disable-verification flashall

After the flash prociess finishes, reboot the phone and check if it succeeds

fastboot reboot

Installing kernel

Now we download the AOSP kernel for Pixel 8, patch it and flash it.

mkdir shiba-kernel && cd shiba-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b android-gs-shusky-6.1-android16
repo sync

Apply the patches

git apply <sifter>/patches-new/sifter-aosp-complete.patch <shiba-kernel>/aosp

Build the kernel

./build_shusky.sh --no//build/kernel/kleaf:use_prebuilt_gki

Flash the image

cd out/shusky/dist
adb reboot bootloader
fastboot oem disable-verity
fastboot oem disable-verification
fastboot flash dtbo dtbo.img
fastboot flash vendor_kernel_boot vendor_kernel_boot.img
fastboot flash boot boot.img
fastboot reboot fastboot
fastboot flash vendor_dlkm vendor_dlkm.img
fastboot flash system_dlkm system_dlkm.img
fastboot reboot bootloader
fastboot reboot

Now the device is able to run tracers and filters generated by filter.

Using Sifter

Installing Syzkaller

Since Sifter leverages Syzkaller’s syscall description to automatically generate tracers and filters, you will need to install Syzkaller before running Sifter’s tracer/filter generator.

Follow the guide to compile and install Syzkaller

Generating tracers using Sifter

git clone https://github.com/trusslab/sifter.git
cd sifter

In Sifter’s directory, generate the eBPF/tracepoints tracer by running the following command

go run sifter_v2.go -mode tracer -config ../syzkalls/src/github.com/google/syzkaller/configs/adb_binder.cfg -fd fd_kgsl -out kgsl

In the default output directory, gen/, you will find the generated source code for the eBPF tracer (e.g., linux_arm64_kgsl.c) and a configuration file you will need later for the agent to load the corresonding tracer (e.g., linux_arm64_kgsl_agent.cfg)

Compiling tracers and the agent

In Android main, create sifter-kern for compiling eBPF tracers and filters

mkdir externel/sifter-kern && cd externel/sifter-kern

Copy the generated eBPF tracer, linux_arm64_xxx.c, to the current directory and create the makefile, Android.bp

bpf {
    name: "linux_arm64_xxx.o",
    srcs: ["linux_arm64_xxx.c"],
    cflags: [
        "-Wall",
        "-Werror",
    ],
}

Compile the tracer

mm

In blueline-aosp, copy and compile the user-space agent

cp -r <sifter>/agent external/ && cd external/agent

Compile the agent

mm

Running tracer

Push the tracer and agent to the device

adb push blueline-aosp/out/target/product/blueline/system/etc/bpf/linux_arm64_xxx.o /etc/bpf/
adb shell mkdir /data/sifter
adb push blueline-aosp/out/target/product/blueline/system/bin/agent /data/sifter/
adb push <sifter>/gen/linux_arm64_xxx_agent.cfg /data/sifter/

Reboot the device and the tracer will be loaded automatically during boot. You can check if the tracer is being loaded successfully by

adb logcat -s bpfloader

To start tracing syscalls of user programs, execute the agent, which will attach the eBPF tracer to the tracepoint hook and log the syscalls of the target program specified by its 16-character-long command ( can be found by running cat /proc//comm). Now you can execute the target program in another terminal. The agent will store the results to the output file periodically. Note that if the output file already exist, the agent will restore the result from it at the beginning.

adb shell /data/sifter/agent -c <agent configuration file> -p <comm> -o <output file>

Analyzing traces and generating filters

After the desired trace is collected, you can analyze and generate eBPF/seccomp filters by feed the trace to sifter again by

go run sifter.go -mode filter -config ../syzkalls/src/github.com/google/syzkaller/configs/adb_binder.cfg -fd fd_kgsl -out kgsl

Acknowledgment

The work was supported in part by NSF Awards #1763172 and #1846230 as well as Google’s 2020 Android Security and PrIvacy REsearch (ASPIRE) Award.