這是一張有關標題為 Git, Yocto, and CVEs: A Complete Guide to Mastering Git Patch for Fixing Open-Source Vulnerabilities 的圖片

Git, Yocto, and CVEs: A Complete Guide to Mastering Git Patch for Fixing Open-Source Vulnerabilities

Explains Git patch workflows; demonstrates git diff/git apply vs. git format-patch/git am; shows Yocto/BitBake CVE patch integration and cve-check verification.

Introduction

In team development, you typically use a shared Git server where members can pull and push code based on their permissions. However, when you need to contribute to a project without push access or under strict controls, a direct push isn’t an option.

This is where the Git patch workflow comes in. It allows you to bundle commits into transferable .patch files. The recipient can then apply these files to their codebase while preserving all original commit information, including the author, date, and message.

Fundamental Git Patch Mechanisms

Git provides two primary methods for generating and applying patches: git diff/git apply and git format-patch/git am. While they may seem similar, they are fundamentally different in functionality and application scenarios.

When to Use Which Method (A Quick Guide)

  • If you only want to share file content differences without preserving commit history, use git diff + git apply.
  • If you need to preserve the original author and commit message for the history, use git format-patch + git am (recommended for formal contributions).

Workflow 1: git diff / git apply (Applying Code Changes Only)

This method is only concerned with differences in file content. The generated .patch file contains no commit metadata, such as the author, date, or commit message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# On local machine A, generate a diff comparing HEAD with the previous commit
# and output it to changes.patch
git diff HEAD~1 HEAD > changes.patch

# On the receiving machine B, check if the patch can be applied cleanly
git apply --check changes.patch

# After confirming, apply the patch to the working directory
git apply changes.patch

# The changes are now in the working directory and need to be manually staged
# and committed
git add .
# The user on machine B creates the commit, overwriting the original author A
git commit -m "Apply upstream patch: description"

Workflow 2: git format-patch / git am (Preserving Author Information)

This is the recommended and more standard approach. The .patch file from format-patch is an email-formatted file that fully preserves all metadata of the original commit. When a maintainer applies it using git am (apply from mailbox), the original commit history is perfectly restored.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# On local machine A, generate a patch file for the latest commit
git format-patch -1 HEAD
# The generated file will be named 0001-commit-message.patch

# Or generate patches for the last 3 commits (will create 0001-..., 0002-..., 0003-...)
git format-patch -3 HEAD

# Or generate a patch for a single specific commit
git format-patch -1 <commit-id>

# On the maintainer's local machine - apply a single patch
git am 0001-*.patch

# Or apply multiple patches at once
git am 000*.patch

# To add a DCO signoff when applying (depending on team policy)
git am --signoff 000*.patch

# Check the log; the commit author will still be the original user A, not the
# user on machine B
git log -1

DCO (Developer Certificate of Origin)

The DCO is a declaration established by the Linux Foundation. Adding a Signed-off-by line signifies that you created the contribution (in whole or in part) and have the right to submit it under the project’s license.

Common usage: Add a signature when applying a patch or creating a commit to preserve origin and accountability.

Examples:

  • git am --signoff 000*.patch
  • git commit -s -m "Your commit message"

After signing, Signed-off-by: Name <you@example.com> will be added to the commit message.

Practical Application in Yocto / BitBake

In embedded Linux development, the Yocto Project is the standard for building custom systems. BitBake builds and assembles numerous open-source packages. CVE fixes are typically added to a recipe as .patch files (referenced via SRC_URI) and automatically applied by BitBake during the do_patch stage.

The primary reason for using .patch files to fix CVEs is to maintain system stability. A product’s Linux kernel often relies on specific package versions to avoid the risks of upgrading.

However, this means you can’t get security updates through simple version bumps. At this point, precise vulnerability patching becomes essential.

This is where commercial-grade software composition analysis (SCA) tools like Vigiles or Black Duck provide value. These tools scan a project’s source code, analyze its open-source components, and identify known vulnerabilities.

Once an SCA tool reports a CVE, the developer’s task is to find pre-made patches from the upstream project or community. These .patch files are then integrated into the Yocto recipe to achieve “fix the vulnerability, not the core” precision maintenance.

Applying a Patch in a Recipe

A Yocto recipe (.bb file) manages source code and patches through the SRC_URI variable. You just need to place the format-patch-generated .patch file in a specified directory and reference it in SRC_URI.

Suppose we need to patch two CVEs for the example-package. The recipe might look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# meta-mylayer/recipes-example/example-package/example-package_1.0.bb

SUMMARY = "An example package"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=..."

# Points to the source code archive
SRC_URI = "https://example.com/downloads/example-package-${PV}.tar.gz"

# Points to the patch files to be applied
# These files should be placed in the
# meta-mylayer/recipes-example/example-package/files/ directory
SRC_URI += "
    file://CVE-2020-12284.patch;striplevel=1
    file://CVE-2021-3566.patch;striplevel=1
"

# If a patch should be applied to a source subdirectory, you can specify
# patchdir
# SRC_URI += "file://fix-in-subdir.patch;patchdir=subdir;striplevel=1"

During Yocto’s build process (do_patch task), BitBake automatically unpacks the source code and applies all patches defined in SRC_URI in order.

It is recommended to name patches with their CVE number (e.g., CVE-2021-3566.patch). This allows automated tools like Yocto’s cve-check to mark it as “Patched” based on the filename. However, this does not confirm whether the patch truly resolves the vulnerability.

Conclusion

Mastering Git’s patch workflow enables more organized and verifiable collaboration. In short: when you only need to apply file differences without preserving commit information, git diff/git apply is a quick choice. When you need to preserve the author, message, and a traceable commit history, prioritize using git format-patch/git am.

In the context of Yocto, adopting patches named by CVE number (e.g., CVE-2021-3566.patch) and adding them via SRC_URI allows BitBake to apply them automatically. This process integrates with auditing tools like cve-check.

However, remember that a filename annotation only indicates a patch has been attempted. You must still confirm the fix through building, testing, and regression verification.

When creating patches, be mindful of special characters and encoding issues in commit titles. Using gitmoji or emoji shortcodes (like :sparkles:) can cause errors when applying the patch due to encoding, font rendering, or Git version differences.

It’s best to use English for commit titles. If you must use another language, avoid special symbols, ensure the file is UTF-8 encoded, and verify that the patch applies correctly.

Finally, for my personal development, I often use git diff --cached | code - to quickly review staged content. If you want to write better commit messages, check out “Easily Write High-Quality Git Commit Messages with GPT Tools”.

References

  1. Git - git-format-patch Documentation
  2. Git - git-am Documentation
  3. Writing a New Recipe — The Yocto Project
Theme Stack designed by Jimmy