Skip to content

Latest commit

 

History

History
390 lines (273 loc) · 8.73 KB

File metadata and controls

390 lines (273 loc) · 8.73 KB

PPatch Partner Usage Guide

This guide documents the expected environment, configuration, command order, and output locations for PPatch Partner.

1. Core Model

PPatch Partner assumes a repeatable experiment unit:

  • A patch file: patches/<poc_id>.patch
  • A POC directory: pocs/<poc_id>/
  • A Linux source tree initialized at a configured tag
  • A base kernel config
  • A VM image and SSH keys

The typical flow is:

  1. Clone and initialize the Linux source tree.
  2. Apply patches and create one git tag per successful patch.
  3. Prepare a per-POC overlay directory.
  4. Extract patch-required config options and build the kernel.
  5. Retry failed builds with compiler diagnostics when useful.
  6. Start QEMU, run POCs, and scan logs for crash signatures.
  7. Optionally run syzkaller reproduction or corpus replay jobs.

2. Configuration Loading

Settings are read from, in order:

  1. Environment variables.
  2. PPATCH_PARTNER_ENV_FILE, if set.
  3. src/ppatch_partner/config/config.env, if it exists.
  4. src/ppatch_partner/config/config.example.env as a safe fallback.

Create a private local config:

cp src/ppatch_partner/config/config.example.env src/ppatch_partner/config/config.env

Keep config.env out of git. It may contain private paths, database URLs, image locations, or SSH key paths.

Path Resolution

WORKSPACE_ROOT is the base directory for relative workspace paths. For example:

WORKSPACE_ROOT=.
LINUX_SOURCE=./linux_source
PATCH_DIR=./patches
WORK_DIR_PATH=./exps

LINUX_DIR is computed as:

<LINUX_SOURCE>/<LTS_VERSION>/<LINUX_TAG>/<LINUX_ARCH>/linux

With the example values, that becomes:

./linux_source/longterm/v6.9.5/x86_64/linux

3. Required Workspace Layout

Create or mount these directories before running full workflows:

.
├── patches/
│   ├── poc_0.patch
│   └── poc_1.patch
├── pocs/
│   ├── poc_0/
│   │   ├── poc
│   │   └── poc.syz
│   └── poc_1/
├── configs/
│   └── x86_64_common_config
├── images/
│   ├── bullseye.img
│   ├── bullseye.id_rsa
│   └── bullseye.id_ed25519
├── linux_source/
├── exps/
└── ppatch_log/

The current VM helper scripts expect a Bullseye image naming convention. If your files are named differently, update src/scripts/startvm, connectvm, scptovm, and related scripts.

4. Host Setup

Install system dependencies:

sudo apt-get update
sudo apt-get install -y \
  build-essential gcc g++ \
  libncurses-dev bison flex libssl-dev libelf-dev \
  git curl wget patch sudo psmisc openssh-client cpio bc \
  qemu-system-x86 qemu-utils

Install Python dependencies:

pdm use -f 3.12
pdm install

Set git identity. The patch workflows create commits and tags inside the Linux source tree:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

5. Docker Setup

Build the image and show CLI help:

docker compose up --build ppatch-partner

Start a shell:

docker compose run --rm ppatch-partner bash

Run a module:

docker compose run --rm ppatch-partner \
  python -m ppatch_partner.scripts.ppatch_auto main --use-gnu-first

Compose starts a local PostgreSQL service. The default credentials are for local development only:

postgresql://ppatch:ppatch@postgres:5432/ppatch_partner

Override them for any shared or long-lived deployment.

6. Initialize Linux Source

Default initialization:

pdm run python -m ppatch_partner.scripts.initialize main

Override key options:

pdm run python -m ppatch_partner.scripts.initialize main \
  --output-dir ./linux_source \
  --lts-version longterm \
  --mirrors-linux-source https://git.kernel.org/pub/scm/linux/kernel/git/stable/ \
  --linux-tag v6.9.5 \
  --linux-arch x86_64

This command:

  • Creates standard workspace directories.
  • Clones <MIRRORS_LINUX_SOURCE><TREE_VERSION>.git.
  • Checks out LINUX_TAG.
  • Adjusts kernel/module/Kconfig.
  • Creates the base tag from LINUX_PATCH_BASE_TAG.

Patch only Kconfig and recreate the base tag:

pdm run python -m ppatch_partner.scripts.initialize fix-kconfig \
  --repo-path ./linux_source/longterm/v6.9.5/x86_64/linux

7. Patch Application

Try GNU patch first, then fall back to ppatch auto:

pdm run python -m ppatch_partner.scripts.ppatch_auto main --use-gnu-first

Use only ppatch auto:

pdm run python -m ppatch_partner.scripts.ppatch_auto main

Outputs:

  • Generated auto patches: ppatch_log/<LTS_VERSION>/<LINUX_TAG>/
  • Failure list: ppatch_log/<LTS_VERSION>/<LINUX_TAG>/failure_patches.txt
  • Linux git commits and tags for successful patches.

Apply multiple patches from a list:

pdm run python -m ppatch_partner.scripts.ppatch_auto apply-multiple \
  --poc-list-file ./multiple.txt

Apply multiple patches using conflict-aware ordering:

pdm run python -m ppatch_partner.scripts.ppatch_auto apply-multiple-optimized \
  --poc-list-file ./multiple.txt \
  --max-patches 20

8. Overlay Builds

Run the complete per-POC overlay workflow:

pdm run python -m ppatch_partner.scripts.overlay auto --cve-id poc_0

Run individual steps:

pdm run python -m ppatch_partner.scripts.overlay init --cve-id poc_0
pdm run python -m ppatch_partner.scripts.overlay mount --cve-id poc_0
pdm run python -m ppatch_partner.scripts.overlay compile-kernel --cve-id poc_0
pdm run python -m ppatch_partner.scripts.overlay unmount --cve-id poc_0

Important output locations:

exps/<poc_id>/<LTS_VERSION>/<LINUX_ARCH>/
exps/compilation_logs/<LTS_VERSION>/<LINUX_TAG>/

The build currently checks for:

upper_dir/arch/x86/boot/bzImage

9. Retry From Compiler Diagnostics

When a build fails, stderr may contain JSON diagnostics. Retry patching from that data:

pdm run python -m ppatch_partner.scripts.auto_ppatch_retry main \
  --cve-id poc_0 \
  --max-retries 3

The retry workflow:

  • Reads stderr_<poc_id>_attempt<N>.log.
  • Extracts JSON diagnostics next to the log.
  • Runs ppatch auto with the diagnostics file.
  • Creates retry tags such as poc_0_retry2.
  • Rebuilds until success or retry exhaustion.

10. Crash Monitoring

Run one POC in QEMU and scan VM logs:

pdm run python -m ppatch_partner.scripts.monitor_crash main --cve-id poc_0

Run a list:

pdm run python -m ppatch_partner.scripts.monitor_crash main \
  --cve-list ./poc_list.txt \
  --concurrency 2

Results are written to:

panic_list.txt
no_panic_list.txt

11. Syzkaller

Run one syzkaller reproduction:

pdm run python -m ppatch_partner.scripts.reproduce single poc_0

Run a batch:

pdm run python -m ppatch_partner.scripts.reproduce batch ./poc_list.txt --run-time 24

Inspect or stop running instances:

pdm run python -m ppatch_partner.scripts.reproduce status
pdm run python -m ppatch_partner.scripts.reproduce stop poc_0
pdm run python -m ppatch_partner.scripts.reproduce stop

Extract corpus databases:

pdm run python -m ppatch_partner.scripts.reproduce extract-corpus-cmd \
  ./poc_list.txt v6.9.5 ./corpus_exports

Load corpus databases and run corpus replay:

pdm run python -m ppatch_partner.scripts.reproduce load-corpus-cmd \
  ./poc_list.txt v6.9.5 ./corpus_exports --run-time 12

12. Cleanup

Clean experiment directories, tags, and temporary files:

pdm run python -m ppatch_partner.scripts.clean main --clean-type all

Clean only Linux worktree state:

pdm run python -m ppatch_partner.scripts.clean main --clean-type git

Clean only tags created by workflows:

pdm run python -m ppatch_partner.scripts.clean main --clean-type tags

13. Troubleshooting

ModuleNotFoundError

Install dependencies through PDM:

pdm install

Python is not 3.12

The project requires Python 3.12:

pdm use -f 3.12

Overlay mount fails

Check:

  • The command is running on Linux.
  • The user can run sudo mount.
  • No stale mount is still attached.
  • The kernel source directory exists.

VM does not boot

Check:

  • qemu-system-x86_64 is installed.
  • KVM is available, or update VM scripts for non-KVM use.
  • images/ contains the expected Bullseye image and SSH keys.
  • startvm is executable in the experiment directory.

Patch tags already exist

The patch workflows skip existing tags. Remove or rename old tags if you need to reprocess a patch:

git -C ./linux_source/longterm/v6.9.5/x86_64/linux tag -d poc_0

Database connection fails

Database persistence is optional. If you are not saving to the database, avoid --save-to-db. If you are using Docker Compose, wait for PostgreSQL health checks to pass.