# Vanir: Missing Patch Scanner
Vanir is a source code-based static analysis tool that automatically identifies
the list of missing security patches in the target system. By default, Vanir
pulls up-to-date CVEs from [Open Source Vulnerabilities (OSV)](https://osv.dev/list?q=&ecosystem=Android)
together with their corresponding signatures so that users can transparently
scan missing patches for an up-to-date list of CVEs. Vanir currently supports
C/C++ and Java source code, and Google-supplied Vanir signatures cover CVEs
published through [Android security bulletins](https://source.android.com/docs/security/bulletin/asb-overview)
since 2020 July. Vanir is primarily designed to detect missing security patches
with low false-positive rate in a sustainable and scalable way.
****
## Quick Start
### Install Vanir as a package using `pip`
1. Install Vanir.
```sh
pip install vanir
```
2. To scan your Android repo project located at ~/my/android/repo, run:
```sh
python -m vanir.detector_runner repo_scanner Android ~/my/android/repo
```
3. Find the missing patches identified by Vanir at `/tmp/vanir/report-YYYYMMDDhhmmss.html` and `/tmp/vanir/report-YYYYMMDDhhmmss.json`.
Alternatively, follow the steps below to use the version from GitHub.
### Clone Vanir from GitHub
> [!CAUTION]
> This instruction is written based on systems using Bazel >= 8. For Bazel 7.1
> and 7.0, edit .bazelrc to enable workspace and disable bzlmod.
> For Bazel 6, remove or comment out the line `common --enable_workspace=False`
> as this flag is not supported.
1. Install the following [prerequisite](#prerequisite) tools in a Linux machine
if not already installed:
* [Bazel](https://bazel.build/install/ubuntu#install-on-ubuntu)
* Git
```posix-terminal
sudo apt install git
```
* JRE >= Java 11
```posix-terminal
sudo apt install openjdk-11-jre
```
2. Download Vanir and move to the Vanir directory.
3. To scan your Android repo project located at `~/my/android/repo`, run:
```posix-terminal
bazel build //:detector_runner
./bazel-bin/detector_runner repo_scanner Android ~/my/android/repo
```
4. Find the missing patches identified by Vanir at `/tmp/vanir/report-YYYYMMDDhhmmss.html` and `/tmp/vanir/report-YYYYMMDDhhmmss.json`
For further details, please see the [User Guide](#user-guide) section.
****
## User Benefits
**Code Variance Tolerance:** Vanir identifies missing security patches from the
customized ones. This can be especially beneficial for downstream branch
maintainers (such as Android device vendors and custom kernel maintainers) who
usually need to make additional changes on the upstream code for adapting
it to their devices and also want to make sure the security of their devices is
aligned with the latest security updates.
**Metadata-agnostic Detection:** Vanir fundamentally does not rely on metadata
of the target system such as version number, commit histories and SBOMs. Vanir
directly analyzes the actual source-code of the target system and pinpoints the
files / functions requiring specific security patches. While Vanir user may
choose to to filter out unwanted findings by providing metadata, its core
detection logic is metadata-agnostic. This allows Vanir users the flexibility to
utilize the tool with various options for different purpose.
**Automated Signature Generation:** The Vanir signature generation process is
highly automated, enabling vulnerability publishers (such as CNAs and ecosystem
security maintainers) to efficiently utilize Vanir and ensure security patch
adoption by their downstream branch maintainers, streamlining workflows and
optimizing resource allocation.
**Runtime:** Since Vanir uses source-code based static analysis to detect
missing patches, the run time will be shorter compared to binary-based static
analysis tools or dynamic analysis tools.
**Transparency:** Vanir operates as a standalone, fully open-source application.
This empowers users to independently investigate and address any vulnerabilities
identified by Vanir, without relying on or being hindered by responses from
external service providers.
**Continuously Updated Vulnerability Data:** The Vanir tool is decoupled from
the vulnerability data, and updated Android vulnerability data for Vanir will
be maintained by the Google Android Security team in [OSV](https://osv.dev/list?q=&ecosystem=Android).
This will allow the Vanir users to simply run the Vanir with the latest
vulnerability data without monthly updates. Further contributions from other
CNAs (CVE Numbering Authorities) or system security maintainers would allow
users to utilize Vanir for other ecosystems.
**CI/CD Integration:** Vanir is also provided in the form of Python library.
Users can integrate the Vanir library into their own automated pipeline to
verify any missing patches in a highly automated and systematic way.
****
## Architectural Overview
### Macro-architecture

Vanir mainly consists of two components — **Signature Generator** and
**Detector**.
**Signature Generator** generates Vanir signatures for each vulnerability. The
vulnerability can be from any source, but it should be defined in a [OSV format](https://ossf.github.io/osv-schema/),
and should contain security patch information in the `references` field in the
following format:
```
"references": [
"type": "FIX",
"url": public URL string to the fix commit
]
```
Vanir currently supports commits hosted in `googlesource.com` and
`git.codelinaro.org`, but it can be easily extended to other hosts by adding new
code extractor classes.
Once the generated signatures are shipped to OSV, the signatures can be
transparently retrieved by **Vanir Detector**. Users may also use custom
signatures by passing a JSON-format signature file to Vanir Detector. This can
be useful for providing signatures of vulnerabilities that are not publicly
announced yet or those for closed-source system.
The diagram below illustrates the macro-architecture of Vanir.
### Micro-architecture
The following diagram depicts the internal architecture of Vanir Signature
Generator and Vanir Detector.

Vanir was primarily designed to detect missing security patches with low
false-positive rate in a sustainable and scalable way. To achieve the goal,
Vanir utilizes multiple techniques in its internal components. This section
offers a concise overview of several key Vanir components and spotlights
specific techniques implemented within these components to support the
overarching design objective.
#### Parser
The **parser** is a core component for extracting structural information from
the target code. Since the original target of Vanir was Android, which consists
of Linux kernel written in C and Android Framework written in C++ and Java, the
current parser is implemented using Antlr4 C/C++ parser and Java parser. Vanir
parser is designed to operate without build-time data. This approach enables
Vanir to generate signatures and detect corresponding code blocks without
requiring a build config.
#### Normalizer and Hasher
The extracted code blocks and structural information are passed to the
**normalizer** and **hasher** components. The normalizer abstracts away
security-insensitive tokens and the hahser convert the group of tokens into a
128-bit hash. The normalizer and hasher process each code block using two
different signature generation techniques:
1. Line-based signature technique using code line n-grams, which is efficient
for tolerating unrelated code mutations in distanced locations.
1. Function-based signature technique using abstracted function body, which is
efficient for tolerating code mutations less likely to affect security.
While each signature type is specialized to tolerate certain types of code
mutations, both approaches were designed conservatively so that they would
not flag unrelated code as vulnerable code block. Vanir combines the two
different approaches and make them complement each other and improve the
overall sensitivity (i.e., lower the false-negative rate).
The line-based and function-based signature generation techniques are inspired
by the code clone detection algorithms proposed by Jang et al. \[1\] and Kim et
al. \[2\], respectively. While there are some differences in the technical
details and implementations, each technique remains closely aligned
algorithmically with its corresponding research work. Reading these papers would
be beneficial for those seeking a deeper understanding of the theoretical
underpinnings.
* [1] [ReDeBug: Finding Unpatched Code Clones in Entire OS Distributions](https://www.ieee-security.org/TC/SP2012/papers/4681a048.pdf)
* [2] [VUDDY: A Scalable Approach for Vulnerable Code Clone Discovery](https://seulbae-security.github.io/pubs/vuddy-sp17.pdf)
#### Refiner
The newly generated signatures are then passed to **Refiner**, which is another
key component of Vanir to ensure low false-positive rate in a scalable and
efficient way. The refiner tests newly generated signatures against the ground
truth files which are already known as patched. The set of ground truth files
for a signature may vary depending on the quality of the vulnerability data.
If provided vulnerability data contains patch information for a single branch
(e.g., upstream), then it simply uses the revision with the patch commit as
the ground truth. If vulnerability data contains patch information for multiple
branches, the refiner tries to test each signature against all different
branches and classifies them different depending on the result
(`bad`, `version-specific`, `global`). Since the refiner automatically filters
out problematic signatures, Vanir signature publishers can easily maintain the
Vanir signature generation and publication process for their vulnerabilities
without significant effort to maintain the quality of the published signatures.
**Detector** follows a similar process of that of signature generation -
it passes possibly affected files from the target system to the parser,
normalizer and hasher, and compares the generated hashes with the given
signatures. If a hash matches with a signature, then detector flags the
corresponding vulnerability.
#### Target Selector
Another unique component in Detector is **Target Selector**. To optimize its
run-time, Vanir tries to identify potentially affected files from the target
system and analyzes only the identified files by default, and the way Vanir
identifies the potentially affected files varies depending on the target
selector. Vanir Detector currently offers three target selection strategies --
`ALL_FILES`, `EXACT_PATH_MATCH` and `TRUNCATED_PATH_MATCH`:
* `ALL_FILES` strategy identifies all files as affected.
* `EXACT_PATH_MATCH` strategy identifies the files exactly matching the
relative path of the files used for signature generation (aka
*target file path*) as affected.
* `TRUNCATED_PATH_MATCH` strategy identifies the files partially matching
the *target file paths* as affected.
As you may imagine, `ALL_FILES` is thorough but slow, while `EXACT_PATH_MATCH`
is fast but may not cover directories and files moved to non-canonical paths.
`TRUNCATED_PATH_MATCH` makes a balance between the two by identifying files
matching subset of the signature's target file paths, allowing the use of Vanir
for scanning complex target systems containing multiple packages in a single
directory (e.g., multiple kernels, duplicated packages, out-of-tree kernel
modules, same packages with different versions) without sacrificing performance.
Vanir uses `TRUNCATED_PATH_MATCH` as a default target selection strategy.
****
## User Guide
### Using the PyPI version
#### Create a virtual environment (recommended to avoid dependency conflicts)
Steps using virtualenv
```sh
virtualenv -p python3 ~/vanir-pip-env
source ~/vanir-pip-env/bin/activate
```
For using specific python version such as `3.13`, steps using pyenv are as
follows:
```sh
pyenv virtualenv 3.13 vanir-3.13
pyenv activate vanir-3.13
```
#### Install and Test Vanir
Install the latest vanir using `pip install` as follows:
```sh
pip install vanir
```
Run the unit tests:
```sh
python -m vanir.pip_modules.pip_test_runner
```
If all tests are successful, you will see the result similar to the following:
```sh
I0624 19:14:22.476867 140398746275584 pip_test_runner.py:134] Pass: vanir.code_extractors.code_extractor_android_test
I0624 19:14:23.066157 140398746275584 pip_test_runner.py:134] Pass: vanir.code_extractors.code_extractor_test
[...]
I0624 19:14:49.976438 140398746275584 pip_test_runner.py:134] Pass: vanir.vulnerability_overwriter_test
I0624 19:14:50.533897 140398746275584 pip_test_runner.py:134] Pass: vanir.vulnerability_test
I0624 19:14:50.534017 140398746275584 pip_test_runner.py:205] Total tests: 31
I0624 19:14:50.534083 140398746275584 pip_test_runner.py:206] Successfully ran 31 tests.
```
If the tests don't pass, please open an issue with the error logs, and we'll
take a look.
#### Run Vanir Detector from the PyPI Vanir
To scan your Android repo project located at ~/my/android/repo, run:
```sh
python -m vanir.detector_runner repo_scanner Android ~/my/android/repo
```
Find the missing patches identified by Vanir at
`/tmp/vanir/report-YYYYMMDDhhmmss.html` and
`/tmp/vanir/report-YYYYMMDDhhmmss.json`.
For more details and examples, please refer to [Run Vanir Detector](#run-vanir-detector)
### Using the GitHub version
#### Prerequisite
##### Linux
Vanir is currently tested only on Linux operating systems. Running Vanir with
other operating systems may be possible, but is neither tested nor officially
supported.
##### Bazel
Vanir builds using [Bazel](https://bazel.build/). The Vanir Bazel configuration
files ([WORKSPACE.bazel](./WORKSPACE.bazel) and [BUILD.bazel](./BUILD.bazel)) specify the complete list of
dependencies and build targets. To understand the complete list of dependencies,
please refer to the Bazel configuration files.
Vanir has been tested with only **Bazel >= 6.0**. The Bazel installation guide
can be found from https://bazel.build/install.
Alternatively, you can install and maintain Bazel through Bazelisk. For further
information on how to install Bazel through Bazelisk, please refer to the
Bazelisk [README](https://github.com/bazelbuild/bazelisk/blob/master/README.md).
##### Git
Though Vanir does not directly use Git at run time, Vanir Bazel build
configuration uses Git for downloading dependencies. If you haven’t installed
Git, run the following command and install it:
```posix-terminal
sudo apt install git
```
##### JRE
Vanir internally uses [Antlr4](https://www.antlr.org/) for generating parsers,
and it requires Java 11 or higher. For Ubuntu, install Java 11 as follow:
```posix-terminal
sudo apt install openjdk-11-jre
```
##### Other Tools
Vanir targets Python3.9 and C++17. For Python, if you use Bazel, Bazel will
internally create a repository and register the toolchain for running Vanir. For
C++, Bazel will not install C++ toolchain but uses the system-installed
toolchain. When you build Vanir, Bazel will implicitly pass the Vanir default
options to your compiler, which are specified in `.bazelrc` including
`-std=c++17`. If your Vanir build fails during compilation, please check the
compatibility of your toolchain with the options listed in `.bazelrc`.
#### Download and Test Vanir
Download the latest version of Vanir from https://github.com/google/vanir.
In this tutorial, we will assume that you downloaded Vanir at `~/vanir`.
> [!CAUTION]
> You can use any work directory instead of `~/vanir`,
> **but please do not use `/tmp/vanir` as your Vanir work directory**.
> `/tmp/vanir` is used for storing temporary files for Vanir unit tests, and
> the test would fail due to the Bazel sandboxing rule if you use the
> `/tmp/vanir` also for storing Vanir source.
If test is successful, you will see the result similar to the following:
```none
Starting local Bazel server and connecting to it...
INFO: Analyzed 74 targets (98 packages loaded, 3902 targets configured).
INFO: Found 48 targets and 26 test targets...
INFO: Elapsed time: 38.840s, Critical Path: 32.83s
INFO: 452 processes: 136 internal, 311 linux-sandbox, 5 local.
INFO: Build completed successfully, 452 total actions
//:detector_common_flags_test PASSED in 1.0s
//:detector_runner_test PASSED in 1.9s
//:file_list_manager_test PASSED in 1.1s
//:hasher_test PASSED in 2.2s
//:normalizer_test PASSED in 2.2s
//:parser_test PASSED in 0.8s
//:refiner_test PASSED in 1.2s
//:reporter_test PASSED in 1.0s
//:sign_generator_runner_test PASSED in 1.1s
//:sign_generator_test PASSED in 1.7s
//:signature_test PASSED in 2.2s
//:truncated_path_test PASSED in 2.6s
//:version_extractor_test PASSED in 2.2s
//:vulnerability_manager_test PASSED in 2.8s
//code_extractors:code_extractor_android_test PASSED in 4.6s
//code_extractors:code_extractor_test PASSED in 3.2s
//integration_tests:missing_patch_detection_hermetic_test PASSED in 7.9s
//language_parsers/cpp:cpp_parser_test PASSED in 0.7s
//language_parsers/java:java_parser_test PASSED in 1.1s
//scanners:android_kernel_scanner_test PASSED in 1.0s
//scanners:offline_directory_scanner_test PASSED in 1.0s
//scanners:package_identifier_test PASSED in 3.2s
//scanners:package_scanner_test PASSED in 1.3s
//scanners:repo_scanner_test PASSED in 1.3s
//scanners:scanner_base_test PASSED in 11.8s
//scanners:target_selection_strategy_test PASSED in 1.1s
Executed 26 out of 26 tests: 26 tests pass.
```
If you installed all required packages listed in the [Prerequisite section](#prerequisite) and
the test still fails, please run the following command and contact us with its
output:
```posix-terminal
bazel test --test_output=all //...
```
> [!NOTE]
> If you encounter "file name too long" error, this may be due to Bazel sandbox
> creating a test directory that is longer than 255 characters. In that case,
> this can be worked around by running bazel or bazelisk with a different output
> dir, like so:
> `bazel --output_user_root=/tmp/mybazeldir test --test_output=all //...`
#### Building Vanir
Vanir mainly consists of two components – Vanir Signature Generator and Vanir
Detector. Vanir signature generator is the component for signature publishes
such as CNAs to generate Vanir signatures, and Vanir Detector is the component
for users to check if their target system has any missing patches for the
provided CVE signatures. The signature generation process is out of scope for
this document, but feel free to look at
`bazel run //:sign_generator_runner -- --help` for how it can be used.
The rest of this document is focused on explaining the use of Vanir Detector.
##### Build Vanir Detector Runner
Though Vanir Detector can be used as a Python library, we also provide Vanir
Detector as a standalone binary target, _Detector Runner_, for easier use. To
build the Vanir Detector Runner binary, run the following command from where you
unpacked Vanir source code (i.e., `~/vanir`):
```posix-terminal
bazel build //:detector_runner --build_python_zip -c opt
```
If the build is successful, you will see a message similar to the following:
```none
INFO: Analyzed target //:detector_runner (0 packages loaded, 3783 targets configured).
INFO: Found 1 target...
Target //:detector_runner up-to-date:
bazel-bin/detector_runner.zip
bazel-bin/detector_runner
INFO: Elapsed time: 12.456s, Critical Path: 11.45s
INFO: 17 processes: 9 internal, 4 linux-sandbox, 4 local.
INFO: Build completed successfully, 17 total actions
```
and the stand-alone binary file will be created at `./bazel-bin/detector_runner` under your Vanir source directory.
> [!NOTE]
> The generated binary is a self-contained binary that contains all
> dependencies. If you don’t need a self-contained binary, you can drop the
> <code>--build_python_zip</code> flag.
> [!NOTE]
> Bazel may sometimes complain about missing dependency declarations on
> standard library headers, e.g. '/usr/lib/gcc/x86\_64-linux-gnu/8/include/stdint.h',
> especially after the system toolchain was updated. Usually running
> `bazel clean --expunge` and rebuilding would resolve the issue.
> [!NOTE]
> You may use `bazel run //:detector_runner` to build and run Vanir detector
> with a single command. However, different from directly running the binary,
> when you run the same command with `bazel run`, the working directory of the
> binary may differ from your current working directory and it may fail to
> parse some arguments with relative paths (e.g., scanning target). Thus, please
> consider using absolute paths with `bazel run`.
#### Signatures
Vanir is designed to decouple the signature release process & the code release
process. In the current implementation, Vanir is configured to retrieve
signatures from Open Source Vulnerability (OSV) databases.
However, if you have custom signature files in a JSON format and need to use
the signatures instead of the ones in OSV, you can pass the files by using the
`vulnerability_file_name` flag as follows:
```posix-terminal
./bazel-bin/detector_runner \
--vulnerability_file_name ~/Downloads/vanir_sigs_android_20240321.json \
--vulnerability_file_name ~/Downloads/vanir_sigs_qualcomm_20240321.json \
...
```
#### Run Vanir Detector
Now, you are ready to run the Vanir Detector Runner to scan missing patches from
your Android tree.
All the examples assume you are currently in the Vanir source directory, and
have downloaded the signature JSON files to `~/Downloads/`.
If you have an Android tree checked out at `~/android-src`, for example, this
would scan all repositories in it against all known signatures:
```posix-terminal
./bazel-bin/detector_runner repo_scanner Android ~/android-src
```
This should take roughly half an hour to scan one AOSP android tree on a modern
consumer PC.
> [!TIP]
> Use the `--verbosity` absl flag to control the amount of run time logging.
> E.g. `--verbosity=-1` will show only WARNING and above logs; `--verbosity=0`
> will display detailed INFO logs (the default behavior); `--verbosity=1` will
> display all logs including DEBUG level messages.
> [!TIP]
> `--vulnerability_file_name `can be specified multiple times, and Vanir will
> scan against all of the specified signatures.
##### Output
By default, Detector Runner will generate report files at
`/tmp/vanir/YYYYMMDDhhmmss.json` and `/tmp/vanir/YYYYMMDDhhmmss.html`. You can
also specify the report file name prefix through the flag `--report_file_name`.
For instance, `--report_file_name=/tmp/foo/bar` will make Vanir to generate
report files `/tmp/foo/bar.json` and `/tmp/foo/bar.html`.
##### Other examples
To run Vanir Detector runner against a local kernel code located at
`/tmp/test_kernel` with the Android kernel vulnerabilities and their
pre-generated signatures:
```posix-terminal
./bazel-bin/detector_runner android_kernel_scanner /tmp/test_kernel
```
To run Vanir Detector Runner against a locally checked out Android
frameworks/base source at `/tmp/test\_fwk\_base`:
```posix-terminal
./bazel-bin/detector_runner \
package_scanner Android platform/frameworks/base /tmp/test_fwk_base
```
To run Vanir Detector Runner against all supported source files in a directory
against all signatures regardless of whether the file names/paths match what the
signature patch is.
> [!NOTE]
> For large projects this may take several hours, and may give false positives
> for similar but different files!
```posix-terminal
./bazel-bin/detector_runner \
{{ '<strong>' }}--target_selection_strategy all_files{{ '</strong>' }} \
offline_directory_scanner /some/directory/with/code
```
##### Some notable command-line options
Vanir Detector Runner supports several optional command line options that allow
users to set the range of vulnerability scanning or to filter out known issues.
For instance, the option `--android_spl=2023-03-05` will have Detector Runner
filter out CVEs released after May 5, 2023.
The option `--cve_id_ignore_list=CVE-1234-12345,CVE-4567-45678` will make Vanir
explicitly ignore findings from the designated two CVEs. Similarly, the
option `--sign_target_path_filter=drivers/nvme` will make Vanir ignore
findings from the NVMe device drivers.
More thorough description of available flags can be obtained from the following
Vanir Detector help command:
```posix-terminal
~/vanir_beta/bazel-bin/detector_runner --help
```
##### Scanners
You may have noticed that Vanir *Detector Runners* has several *Scanners*, each
of which can be used to scan a different type of target. We have shown how to
use `repo_scanner` to run scan against an entire Android tree managed with
`repo`, `package_scanner` to scan one Android subproject,
`android_kernel_scanner` for special handling of Android kernel git
repositories, and `offline_directory_scanner` for general scanning of anything
against everything.
To get a list of all options and available Vanir scanners, run:
```posix-terminal
./bazel-bin/detector_runner
```
To get usage for a particular scanner, select that scanner without providing any
argument, e.g. to see how repo scanner can be used, run:
```posix-terminal
./bazel-bin/detector_runner repo_scanner
```
…which should show:
```
…
Usage for repo_scanner:
detector_runner.py repo_scanner ecosystem code_location
```
#### Looking at Results
For a modern PC with ~16 CPU threads, Vanir can take around 10-20 minutes to
finish scanning an Android source tree (the time may vary depending on the
execution environment). Once the test is completed, Vanir Detector Runner will
output a quick summary of the result, similar to:
```none
Scanned 833 source files (skipped 106253 source files likely unaffected by known vulnerabilities).
Found 12 potentially unpatched vulnerabilities: CVE-2020-11116, CVE-2020-26139, CVE-2020-26141, CVE-2020-26145, CVE-2020-26146, CVE-2020-3698, CVE-2021-0476, CVE-2021-1977, CVE-2021-30319, CVE-2022-22065, CVE-2022-25670, CVE-2023-43534
Detailed report:
- /tmp/vanir/report-20240321182302.html
- /tmp/vanir/report-20240321182302.json
```
and the detailed test result reports will be generated in /tmp/vanir/ directory
(or at wherever specified with `--report_file_name`).
The following is an example Vanir Detector Runner JSON report file (which is
more machine readable):
```json
{
"options": "--target_root=/tmp/test_kernel_simple --vulnerability_file_name=/tmp/vanir_vul_with_sign_20230705.json",
"covered_cves": [
"CVE-2017-18509",
...
"CVE-2023-20938"
],
"missing_patches": [
{
"ID": "ASB-A-174737742",
"CVE": [
"CVE-2020-15436"
],
"OSV": "https://osv.dev/vulnerability/ASB-A-174737742",
"details": [
{
"unpatched_code": "fs/block_dev.c::blkdev_get",
"patch": "https://android.googlesource.com/kernel/common/+/49289b1fa5a67011",
"matched_signature": "ASB-A-174737742-1030258c"
},
{
"unpatched_code": "fs/block_dev.c",
"patch": "https://android.googlesource.com/kernel/common/+/49289b1fa5a67011",
"matched_signature": "ASB-A-174737742-339e9e91"
}
]
},
...
{
"ID": "ASB-A-185125206",
"CVE": [
"CVE-2021-39698"
],
"OSV": "https://osv.dev/vulnerability/ASB-A-185125206",
"details": [
{
"unpatched_code": "fs/signalfd.c::signalfd_cleanup",
"patch": "https://android.googlesource.com/kernel/common/+/9537bae0da1f",
"matched_signature": "ASB-A-185125206-c9d43168"
},
{
"unpatched_code": "fs/signalfd.c",
"patch": "https://android.googlesource.com/kernel/common/+/9537bae0da1f",
"matched_signature": "ASB-A-185125206-e8972c8a"
}
]
}
]
}
```
The JSON report file presents the result in a key-value structure, where the
meaning of each key is as follows:
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tr>
<td><strong><code>options</code></strong>
</td>
<td>Explicitly passed command options
</td>
</tr>
<tr>
<td><strong><code>covered_cves</code></strong>
</td>
<td>List of the CVEs covered by Vanir.
</td>
</tr>
<tr>
<td><strong><code>missing_patch</code></strong>
</td>
<td>A list of the detailed information of each unpatched CVE. <strong><code>ID</code></strong> is a unique ID of the vulnerability used in OSV, and <strong><code>CVE</code></strong> is a list of CVE aliases (most vulnerabilities have a single CVE entry). <strong><code>OSV</code></strong> is the public OSV URL of the vulnerability, which has more details of the vulnerability entry information if the CVE is not embargoed. <br/>
The <strong><code>details</code></strong> field is a list of unpatched code snippets in the following formats:
<table>
<tr>
<td><strong><code>unpatched_code</code></strong>
</td>
<td>The relative path to the unpatched file and the function from the scanned target root.
</td>
</tr>
<tr>
<td><strong><code>patch</code></strong>
</td>
<td>The public URL to the patch that should be applied.
</td>
</tr>
<tr>
<td><strong><code>matched_signature</code></strong>
</td>
<td>The unique ID of the matched signature. The details can be found from the <strong><code>$VUL_FILE</code></strong> passed to the detector.
</td>
</tr>
</table>
</td>
</tr>
</table>
The HTML report file shows the same result in a more human-readable format as
follows:

Raw data
{
"_id": null,
"home_page": null,
"name": "vanir",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.14,>=3.9",
"maintainer_email": "\"Hyunwook (Wooky) Baek\" <baekhw@google.com>, Duy Truong <duytruong@google.com>, Justin Dunlap <justindunlap@google.com>",
"keywords": "static analysis, source code analysis, missing patch scanner",
"author": null,
"author_email": "\"Hyunwook (Wooky) Baek\" <baekhw@google.com>, Duy Truong <duytruong@google.com>, Justin Dunlap <justindunlap@google.com>",
"download_url": "https://files.pythonhosted.org/packages/48/15/f920cb312f172835a6d2770fc3b0d77b4b14b11ff4d8ff0dbc6850828485/vanir-1.0.1.tar.gz",
"platform": null,
"description": "# Vanir: Missing Patch Scanner\n\nVanir is a source code-based static analysis tool that automatically identifies\nthe list of missing security patches in the target system. By default, Vanir\npulls up-to-date CVEs from [Open Source Vulnerabilities (OSV)](https://osv.dev/list?q=&ecosystem=Android)\ntogether with their corresponding signatures so that users can transparently\nscan missing patches for an up-to-date list of CVEs. Vanir currently supports\nC/C++ and Java source code, and Google-supplied Vanir signatures cover CVEs\npublished through [Android security bulletins](https://source.android.com/docs/security/bulletin/asb-overview)\nsince 2020 July. Vanir is primarily designed to detect missing security patches\nwith low false-positive rate in a sustainable and scalable way.\n\n****\n\n## Quick Start\n\n### Install Vanir as a package using `pip`\n\n1. Install Vanir.\n\n ```sh\n pip install vanir\n ```\n\n2. To scan your Android repo project located at ~/my/android/repo, run:\n\n ```sh\n python -m vanir.detector_runner repo_scanner Android ~/my/android/repo\n ```\n\n3. Find the missing patches identified by Vanir at `/tmp/vanir/report-YYYYMMDDhhmmss.html` and `/tmp/vanir/report-YYYYMMDDhhmmss.json`.\n\nAlternatively, follow the steps below to use the version from GitHub.\n\n### Clone Vanir from GitHub\n> [!CAUTION]\n> This instruction is written based on systems using Bazel >= 8. For Bazel 7.1\n> and 7.0, edit .bazelrc to enable workspace and disable bzlmod.\n> For Bazel 6, remove or comment out the line `common --enable_workspace=False`\n> as this flag is not supported.\n\n1. Install the following [prerequisite](#prerequisite) tools in a Linux machine\nif not already installed:\n\n * [Bazel](https://bazel.build/install/ubuntu#install-on-ubuntu)\n * Git\n\n ```posix-terminal\n sudo apt install git\n ```\n\n * JRE >= Java 11\n\n ```posix-terminal\n sudo apt install openjdk-11-jre\n ```\n\n2. Download Vanir and move to the Vanir directory.\n\n3. To scan your Android repo project located at `~/my/android/repo`, run:\n\n ```posix-terminal\n bazel build //:detector_runner\n ./bazel-bin/detector_runner repo_scanner Android ~/my/android/repo\n ```\n\n4. Find the missing patches identified by Vanir at `/tmp/vanir/report-YYYYMMDDhhmmss.html` and `/tmp/vanir/report-YYYYMMDDhhmmss.json`\n\nFor further details, please see the [User Guide](#user-guide) section.\n\n****\n\n## User Benefits\n\n**Code Variance Tolerance:** Vanir identifies missing security patches from the\ncustomized ones. This can be especially beneficial for downstream branch\nmaintainers (such as Android device vendors and custom kernel maintainers) who\nusually need to make additional changes on the upstream code for adapting\nit to their devices and also want to make sure the security of their devices is\naligned with the latest security updates.\n\n**Metadata-agnostic Detection:** Vanir fundamentally does not rely on metadata\nof the target system such as version number, commit histories and SBOMs. Vanir\ndirectly analyzes the actual source-code of the target system and pinpoints the\nfiles / functions requiring specific security patches. While Vanir user may\nchoose to to filter out unwanted findings by providing metadata, its core\ndetection logic is metadata-agnostic. This allows Vanir users the flexibility to\nutilize the tool with various options for different purpose.\n\n**Automated Signature Generation:** The Vanir signature generation process is\nhighly automated, enabling vulnerability publishers (such as CNAs and ecosystem\nsecurity maintainers) to efficiently utilize Vanir and ensure security patch\nadoption by their downstream branch maintainers, streamlining workflows and\noptimizing resource allocation.\n\n**Runtime:** Since Vanir uses source-code based static analysis to detect\nmissing patches, the run time will be shorter compared to binary-based static\nanalysis tools or dynamic analysis tools.\n\n**Transparency:** Vanir operates as a standalone, fully open-source application.\nThis empowers users to independently investigate and address any vulnerabilities\nidentified by Vanir, without relying on or being hindered by responses from\nexternal service providers.\n\n**Continuously Updated Vulnerability Data:** The Vanir tool is decoupled from\nthe vulnerability data, and updated Android vulnerability data for Vanir will\nbe maintained by the Google Android Security team in [OSV](https://osv.dev/list?q=&ecosystem=Android).\nThis will allow the Vanir users to simply run the Vanir with the latest\nvulnerability data without monthly updates. Further contributions from other\nCNAs (CVE Numbering Authorities) or system security maintainers would allow\nusers to utilize Vanir for other ecosystems.\n\n**CI/CD Integration:** Vanir is also provided in the form of Python library.\nUsers can integrate the Vanir library into their own automated pipeline to\nverify any missing patches in a highly automated and systematic way.\n\n****\n\n## Architectural Overview\n\n### Macro-architecture\n\n\n\nVanir mainly consists of two components \u2014 **Signature Generator** and\n**Detector**.\n\n**Signature Generator** generates Vanir signatures for each vulnerability. The\nvulnerability can be from any source, but it should be defined in a [OSV format](https://ossf.github.io/osv-schema/),\nand should contain security patch information in the `references` field in the\nfollowing format:\n\n```\n\"references\": [\n \"type\": \"FIX\",\n \"url\": public URL string to the fix commit\n]\n```\n\nVanir currently supports commits hosted in `googlesource.com` and\n`git.codelinaro.org`, but it can be easily extended to other hosts by adding new\ncode extractor classes.\n\nOnce the generated signatures are shipped to OSV, the signatures can be\ntransparently retrieved by **Vanir Detector**. Users may also use custom\nsignatures by passing a JSON-format signature file to Vanir Detector. This can\nbe useful for providing signatures of vulnerabilities that are not publicly\nannounced yet or those for closed-source system.\n\nThe diagram below illustrates the macro-architecture of Vanir.\n\n### Micro-architecture\n\nThe following diagram depicts the internal architecture of Vanir Signature\nGenerator and Vanir Detector.\n\n\n\nVanir was primarily designed to detect missing security patches with low\nfalse-positive rate in a sustainable and scalable way. To achieve the goal,\nVanir utilizes multiple techniques in its internal components. This section\noffers a concise overview of several key Vanir components and spotlights\nspecific techniques implemented within these components to support the\noverarching design objective.\n\n#### Parser\n\nThe **parser** is a core component for extracting structural information from\nthe target code. Since the original target of Vanir was Android, which consists\nof Linux kernel written in C and Android Framework written in C++ and Java, the\ncurrent parser is implemented using Antlr4 C/C++ parser and Java parser. Vanir\nparser is designed to operate without build-time data. This approach enables\nVanir to generate signatures and detect corresponding code blocks without\nrequiring a build config.\n\n#### Normalizer and Hasher\n\nThe extracted code blocks and structural information are passed to the\n**normalizer** and **hasher** components. The normalizer abstracts away\nsecurity-insensitive tokens and the hahser convert the group of tokens into a\n128-bit hash. The normalizer and hasher process each code block using two\ndifferent signature generation techniques:\n\n1. Line-based signature technique using code line n-grams, which is efficient\nfor tolerating unrelated code mutations in distanced locations.\n\n1. Function-based signature technique using abstracted function body, which is\nefficient for tolerating code mutations less likely to affect security.\n\nWhile each signature type is specialized to tolerate certain types of code\nmutations, both approaches were designed conservatively so that they would\nnot flag unrelated code as vulnerable code block. Vanir combines the two\ndifferent approaches and make them complement each other and improve the\noverall sensitivity (i.e., lower the false-negative rate).\n\nThe line-based and function-based signature generation techniques are inspired\nby the code clone detection algorithms proposed by Jang et al. \\[1\\] and Kim et\nal. \\[2\\], respectively. While there are some differences in the technical\ndetails and implementations, each technique remains closely aligned\nalgorithmically with its corresponding research work. Reading these papers would\nbe beneficial for those seeking a deeper understanding of the theoretical\nunderpinnings.\n\n * [1] [ReDeBug: Finding Unpatched Code Clones in Entire OS Distributions](https://www.ieee-security.org/TC/SP2012/papers/4681a048.pdf)\n * [2] [VUDDY: A Scalable Approach for Vulnerable Code Clone Discovery](https://seulbae-security.github.io/pubs/vuddy-sp17.pdf)\n\n\n#### Refiner\n\nThe newly generated signatures are then passed to **Refiner**, which is another\nkey component of Vanir to ensure low false-positive rate in a scalable and\nefficient way. The refiner tests newly generated signatures against the ground\ntruth files which are already known as patched. The set of ground truth files\nfor a signature may vary depending on the quality of the vulnerability data.\nIf provided vulnerability data contains patch information for a single branch\n(e.g., upstream), then it simply uses the revision with the patch commit as\nthe ground truth. If vulnerability data contains patch information for multiple\nbranches, the refiner tries to test each signature against all different\nbranches and classifies them different depending on the result\n(`bad`, `version-specific`, `global`). Since the refiner automatically filters\nout problematic signatures, Vanir signature publishers can easily maintain the\nVanir signature generation and publication process for their vulnerabilities\nwithout significant effort to maintain the quality of the published signatures.\n\n**Detector** follows a similar process of that of signature generation -\nit passes possibly affected files from the target system to the parser,\nnormalizer and hasher, and compares the generated hashes with the given\nsignatures. If a hash matches with a signature, then detector flags the\ncorresponding vulnerability.\n\n#### Target Selector\n\nAnother unique component in Detector is **Target Selector**. To optimize its\nrun-time, Vanir tries to identify potentially affected files from the target\nsystem and analyzes only the identified files by default, and the way Vanir\nidentifies the potentially affected files varies depending on the target\nselector. Vanir Detector currently offers three target selection strategies --\n`ALL_FILES`, `EXACT_PATH_MATCH` and `TRUNCATED_PATH_MATCH`:\n\n * `ALL_FILES` strategy identifies all files as affected.\n * `EXACT_PATH_MATCH` strategy identifies the files exactly matching the\n relative path of the files used for signature generation (aka\n*target file path*) as affected.\n * `TRUNCATED_PATH_MATCH` strategy identifies the files partially matching\nthe *target file paths* as affected.\n\nAs you may imagine, `ALL_FILES` is thorough but slow, while `EXACT_PATH_MATCH`\nis fast but may not cover directories and files moved to non-canonical paths.\n`TRUNCATED_PATH_MATCH` makes a balance between the two by identifying files\nmatching subset of the signature's target file paths, allowing the use of Vanir\nfor scanning complex target systems containing multiple packages in a single\ndirectory (e.g., multiple kernels, duplicated packages, out-of-tree kernel\nmodules, same packages with different versions) without sacrificing performance.\nVanir uses `TRUNCATED_PATH_MATCH` as a default target selection strategy.\n\n****\n\n## User Guide\n\n### Using the PyPI version\n\n#### Create a virtual environment (recommended to avoid dependency conflicts)\n\nSteps using virtualenv\n\n```sh\nvirtualenv -p python3 ~/vanir-pip-env\nsource ~/vanir-pip-env/bin/activate\n```\n\nFor using specific python version such as `3.13`, steps using pyenv are as\nfollows:\n\n```sh\npyenv virtualenv 3.13 vanir-3.13\npyenv activate vanir-3.13\n```\n\n#### Install and Test Vanir\n\nInstall the latest vanir using `pip install` as follows:\n\n```sh\npip install vanir\n```\n\nRun the unit tests:\n\n```sh\npython -m vanir.pip_modules.pip_test_runner\n```\n\nIf all tests are successful, you will see the result similar to the following:\n\n```sh\nI0624 19:14:22.476867 140398746275584 pip_test_runner.py:134] Pass: vanir.code_extractors.code_extractor_android_test\nI0624 19:14:23.066157 140398746275584 pip_test_runner.py:134] Pass: vanir.code_extractors.code_extractor_test\n[...]\nI0624 19:14:49.976438 140398746275584 pip_test_runner.py:134] Pass: vanir.vulnerability_overwriter_test\nI0624 19:14:50.533897 140398746275584 pip_test_runner.py:134] Pass: vanir.vulnerability_test\nI0624 19:14:50.534017 140398746275584 pip_test_runner.py:205] Total tests: 31\nI0624 19:14:50.534083 140398746275584 pip_test_runner.py:206] Successfully ran 31 tests.\n```\n\nIf the tests don't pass, please open an issue with the error logs, and we'll\ntake a look.\n\n#### Run Vanir Detector from the PyPI Vanir\n\nTo scan your Android repo project located at ~/my/android/repo, run:\n\n```sh\npython -m vanir.detector_runner repo_scanner Android ~/my/android/repo\n```\n\nFind the missing patches identified by Vanir at\n`/tmp/vanir/report-YYYYMMDDhhmmss.html` and\n`/tmp/vanir/report-YYYYMMDDhhmmss.json`.\n\nFor more details and examples, please refer to [Run Vanir Detector](#run-vanir-detector)\n\n### Using the GitHub version\n\n#### Prerequisite\n\n##### Linux\n\nVanir is currently tested only on Linux operating systems. Running Vanir with\nother operating systems may be possible, but is neither tested nor officially\nsupported.\n\n\n##### Bazel\n\nVanir builds using [Bazel](https://bazel.build/). The Vanir Bazel configuration\nfiles ([WORKSPACE.bazel](./WORKSPACE.bazel) and [BUILD.bazel](./BUILD.bazel)) specify the complete list of\ndependencies and build targets. To understand the complete list of dependencies,\n please refer to the Bazel configuration files.\n\nVanir has been tested with only **Bazel >= 6.0**. The Bazel installation guide\ncan be found from https://bazel.build/install.\n\nAlternatively, you can install and maintain Bazel through Bazelisk. For further\ninformation on how to install Bazel through Bazelisk, please refer to the\nBazelisk [README](https://github.com/bazelbuild/bazelisk/blob/master/README.md).\n\n\n##### Git\n\nThough Vanir does not directly use Git at run time, Vanir Bazel build\nconfiguration uses Git for downloading dependencies. If you haven\u2019t installed\nGit, run the following command and install it:\n\n```posix-terminal\nsudo apt install git\n```\n\n##### JRE\n\nVanir internally uses [Antlr4](https://www.antlr.org/) for generating parsers,\nand it requires Java 11 or higher. For Ubuntu, install Java 11 as follow:\n\n```posix-terminal\nsudo apt install openjdk-11-jre\n```\n\n##### Other Tools\n\nVanir targets Python3.9 and C++17. For Python, if you use Bazel, Bazel will\ninternally create a repository and register the toolchain for running Vanir. For\n C++, Bazel will not install C++ toolchain but uses the system-installed\n toolchain. When you build Vanir, Bazel will implicitly pass the Vanir default\n options to your compiler, which are specified in `.bazelrc` including\n `-std=c++17`. If your Vanir build fails during compilation, please check the\n compatibility of your toolchain with the options listed in `.bazelrc`.\n\n\n#### Download and Test Vanir\n\nDownload the latest version of Vanir from https://github.com/google/vanir.\nIn this tutorial, we will assume that you downloaded Vanir at `~/vanir`.\n\n> [!CAUTION]\n> You can use any work directory instead of `~/vanir`,\n> **but please do not use `/tmp/vanir` as your Vanir work directory**.\n> `/tmp/vanir` is used for storing temporary files for Vanir unit tests, and\n> the test would fail due to the Bazel sandboxing rule if you use the\n> `/tmp/vanir` also for storing Vanir source.\n\nIf test is successful, you will see the result similar to the following:\n\n```none\nStarting local Bazel server and connecting to it...\nINFO: Analyzed 74 targets (98 packages loaded, 3902 targets configured).\nINFO: Found 48 targets and 26 test targets...\nINFO: Elapsed time: 38.840s, Critical Path: 32.83s\nINFO: 452 processes: 136 internal, 311 linux-sandbox, 5 local.\nINFO: Build completed successfully, 452 total actions\n//:detector_common_flags_test PASSED in 1.0s\n//:detector_runner_test PASSED in 1.9s\n//:file_list_manager_test PASSED in 1.1s\n//:hasher_test PASSED in 2.2s\n//:normalizer_test PASSED in 2.2s\n//:parser_test PASSED in 0.8s\n//:refiner_test PASSED in 1.2s\n//:reporter_test PASSED in 1.0s\n//:sign_generator_runner_test PASSED in 1.1s\n//:sign_generator_test PASSED in 1.7s\n//:signature_test PASSED in 2.2s\n//:truncated_path_test PASSED in 2.6s\n//:version_extractor_test PASSED in 2.2s\n//:vulnerability_manager_test PASSED in 2.8s\n//code_extractors:code_extractor_android_test PASSED in 4.6s\n//code_extractors:code_extractor_test PASSED in 3.2s\n//integration_tests:missing_patch_detection_hermetic_test PASSED in 7.9s\n//language_parsers/cpp:cpp_parser_test PASSED in 0.7s\n//language_parsers/java:java_parser_test PASSED in 1.1s\n//scanners:android_kernel_scanner_test PASSED in 1.0s\n//scanners:offline_directory_scanner_test PASSED in 1.0s\n//scanners:package_identifier_test PASSED in 3.2s\n//scanners:package_scanner_test PASSED in 1.3s\n//scanners:repo_scanner_test PASSED in 1.3s\n//scanners:scanner_base_test PASSED in 11.8s\n//scanners:target_selection_strategy_test PASSED in 1.1s\n\nExecuted 26 out of 26 tests: 26 tests pass.\n```\n\nIf you installed all required packages listed in the [Prerequisite section](#prerequisite) and\nthe test still fails, please run the following command and contact us with its\noutput:\n\n```posix-terminal\nbazel test --test_output=all //...\n```\n> [!NOTE]\n> If you encounter \"file name too long\" error, this may be due to Bazel sandbox\n> creating a test directory that is longer than 255 characters. In that case,\n> this can be worked around by running bazel or bazelisk with a different output\n> dir, like so:\n> `bazel --output_user_root=/tmp/mybazeldir test --test_output=all //...`\n\n#### Building Vanir\n\nVanir mainly consists of two components \u2013 Vanir Signature Generator and Vanir\nDetector. Vanir signature generator is the component for signature publishes\nsuch as CNAs to generate Vanir signatures, and Vanir Detector is the component\nfor users to check if their target system has any missing patches for the\nprovided CVE signatures. The signature generation process is out of scope for\nthis document, but feel free to look at\n`bazel run //:sign_generator_runner -- --help` for how it can be used.\nThe rest of this document is focused on explaining the use of Vanir Detector.\n\n##### Build Vanir Detector Runner\n\nThough Vanir Detector can be used as a Python library, we also provide Vanir\nDetector as a standalone binary target, _Detector Runner_, for easier use. To\nbuild the Vanir Detector Runner binary, run the following command from where you\nunpacked Vanir source code (i.e., `~/vanir`):\n\n```posix-terminal\nbazel build //:detector_runner --build_python_zip -c opt\n```\n\nIf the build is successful, you will see a message similar to the following:\n\n\n```none\nINFO: Analyzed target //:detector_runner (0 packages loaded, 3783 targets configured).\nINFO: Found 1 target...\nTarget //:detector_runner up-to-date:\n bazel-bin/detector_runner.zip\n bazel-bin/detector_runner\nINFO: Elapsed time: 12.456s, Critical Path: 11.45s\nINFO: 17 processes: 9 internal, 4 linux-sandbox, 4 local.\nINFO: Build completed successfully, 17 total actions\n```\n\nand the stand-alone binary file will be created at `./bazel-bin/detector_runner` under your Vanir source directory.\n\n> [!NOTE]\n> The generated binary is a self-contained binary that contains all\n> dependencies. If you don\u2019t need a self-contained binary, you can drop the\n> <code>--build_python_zip</code> flag.\n\n> [!NOTE]\n> Bazel may sometimes complain about missing dependency declarations on\n> standard library headers, e.g. '/usr/lib/gcc/x86\\_64-linux-gnu/8/include/stdint.h',\n> especially after the system toolchain was updated. Usually running\n> `bazel clean --expunge` and rebuilding would resolve the issue.\n\n> [!NOTE]\n> You may use `bazel run //:detector_runner` to build and run Vanir detector\n> with a single command. However, different from directly running the binary,\n> when you run the same command with `bazel run`, the working directory of the\n> binary may differ from your current working directory and it may fail to\n> parse some arguments with relative paths (e.g., scanning target). Thus, please\n> consider using absolute paths with `bazel run`.\n\n\n#### Signatures\n\nVanir is designed to decouple the signature release process & the code release\nprocess. In the current implementation, Vanir is configured to retrieve\nsignatures from Open Source Vulnerability (OSV) databases.\n\nHowever, if you have custom signature files in a JSON format and need to use\nthe signatures instead of the ones in OSV, you can pass the files by using the\n`vulnerability_file_name` flag as follows:\n\n```posix-terminal\n./bazel-bin/detector_runner \\\n --vulnerability_file_name ~/Downloads/vanir_sigs_android_20240321.json \\\n --vulnerability_file_name ~/Downloads/vanir_sigs_qualcomm_20240321.json \\\n ...\n```\n\n\n#### Run Vanir Detector\n\nNow, you are ready to run the Vanir Detector Runner to scan missing patches from\n your Android tree.\n\nAll the examples assume you are currently in the Vanir source directory, and\nhave downloaded the signature JSON files to `~/Downloads/`.\n\nIf you have an Android tree checked out at `~/android-src`, for example, this\nwould scan all repositories in it against all known signatures:\n\n```posix-terminal\n./bazel-bin/detector_runner repo_scanner Android ~/android-src\n```\n\nThis should take roughly half an hour to scan one AOSP android tree on a modern\nconsumer PC.\n\n> [!TIP]\n> Use the `--verbosity` absl flag to control the amount of run time logging.\n> E.g. `--verbosity=-1` will show only WARNING and above logs; `--verbosity=0`\n> will display detailed INFO logs (the default behavior); `--verbosity=1` will\n> display all logs including DEBUG level messages.\n\n> [!TIP]\n> `--vulnerability_file_name `can be specified multiple times, and Vanir will\n> scan against all of the specified signatures.\n\n\n##### Output\n\nBy default, Detector Runner will generate report files at\n`/tmp/vanir/YYYYMMDDhhmmss.json` and `/tmp/vanir/YYYYMMDDhhmmss.html`. You can\nalso specify the report file name prefix through the flag `--report_file_name`.\nFor instance, `--report_file_name=/tmp/foo/bar` will make Vanir to generate\nreport files `/tmp/foo/bar.json` and `/tmp/foo/bar.html`.\n\n\n##### Other examples\n\nTo run Vanir Detector runner against a local kernel code located at\n`/tmp/test_kernel` with the Android kernel vulnerabilities and their\npre-generated signatures:\n\n```posix-terminal\n./bazel-bin/detector_runner android_kernel_scanner /tmp/test_kernel\n```\n\nTo run Vanir Detector Runner against a locally checked out Android\nframeworks/base source at `/tmp/test\\_fwk\\_base`:\n\n```posix-terminal\n./bazel-bin/detector_runner \\\n package_scanner Android platform/frameworks/base /tmp/test_fwk_base\n```\n\nTo run Vanir Detector Runner against all supported source files in a directory\nagainst all signatures regardless of whether the file names/paths match what the\nsignature patch is.\n\n> [!NOTE]\n> For large projects this may take several hours, and may give false positives\n> for similar but different files!\n\n```posix-terminal\n./bazel-bin/detector_runner \\\n {{ '<strong>' }}--target_selection_strategy all_files{{ '</strong>' }} \\\n offline_directory_scanner /some/directory/with/code\n```\n\n\n##### Some notable command-line options\n\nVanir Detector Runner supports several optional command line options that allow\nusers to set the range of vulnerability scanning or to filter out known issues.\nFor instance, the option `--android_spl=2023-03-05` will have Detector Runner\nfilter out CVEs released after May 5, 2023.\n\nThe option `--cve_id_ignore_list=CVE-1234-12345,CVE-4567-45678` will make Vanir\nexplicitly ignore findings from the designated two CVEs. Similarly, the\noption `--sign_target_path_filter=drivers/nvme` will make Vanir ignore\nfindings from the NVMe device drivers.\n\nMore thorough description of available flags can be obtained from the following\nVanir Detector help command:\n\n```posix-terminal\n~/vanir_beta/bazel-bin/detector_runner --help\n```\n\n##### Scanners\n\nYou may have noticed that Vanir *Detector Runners* has several *Scanners*, each\nof which can be used to scan a different type of target. We have shown how to\nuse `repo_scanner` to run scan against an entire Android tree managed with\n`repo`, `package_scanner` to scan one Android subproject,\n`android_kernel_scanner` for special handling of Android kernel git\nrepositories, and `offline_directory_scanner` for general scanning of anything\nagainst everything.\n\nTo get a list of all options and available Vanir scanners, run:\n\n```posix-terminal\n./bazel-bin/detector_runner\n```\n\nTo get usage for a particular scanner, select that scanner without providing any\nargument, e.g. to see how repo scanner can be used, run:\n\n```posix-terminal\n./bazel-bin/detector_runner repo_scanner\n```\n\n\u2026which should show:\n\n```\n\u2026\nUsage for repo_scanner:\n detector_runner.py repo_scanner ecosystem code_location\n```\n\n#### Looking at Results\n\nFor a modern PC with ~16 CPU threads, Vanir can take around 10-20 minutes to\nfinish scanning an Android source tree (the time may vary depending on the\nexecution environment). Once the test is completed, Vanir Detector Runner will\noutput a quick summary of the result, similar to:\n\n\n```none\nScanned 833 source files (skipped 106253 source files likely unaffected by known vulnerabilities).\nFound 12 potentially unpatched vulnerabilities: CVE-2020-11116, CVE-2020-26139, CVE-2020-26141, CVE-2020-26145, CVE-2020-26146, CVE-2020-3698, CVE-2021-0476, CVE-2021-1977, CVE-2021-30319, CVE-2022-22065, CVE-2022-25670, CVE-2023-43534\nDetailed report:\n - /tmp/vanir/report-20240321182302.html\n - /tmp/vanir/report-20240321182302.json\n```\n\n\nand the detailed test result reports will be generated in /tmp/vanir/ directory\n(or at wherever specified with `--report_file_name`).\n\nThe following is an example Vanir Detector Runner JSON report file (which is\nmore machine readable):\n\n\n```json\n{\n \"options\": \"--target_root=/tmp/test_kernel_simple --vulnerability_file_name=/tmp/vanir_vul_with_sign_20230705.json\",\n \"covered_cves\": [\n \"CVE-2017-18509\",\n ...\n \"CVE-2023-20938\"\n ],\n \"missing_patches\": [\n {\n \"ID\": \"ASB-A-174737742\",\n \"CVE\": [\n \"CVE-2020-15436\"\n ],\n \"OSV\": \"https://osv.dev/vulnerability/ASB-A-174737742\",\n \"details\": [\n {\n \"unpatched_code\": \"fs/block_dev.c::blkdev_get\",\n \"patch\": \"https://android.googlesource.com/kernel/common/+/49289b1fa5a67011\",\n \"matched_signature\": \"ASB-A-174737742-1030258c\"\n },\n {\n \"unpatched_code\": \"fs/block_dev.c\",\n \"patch\": \"https://android.googlesource.com/kernel/common/+/49289b1fa5a67011\",\n \"matched_signature\": \"ASB-A-174737742-339e9e91\"\n }\n ]\n },\n ...\n {\n \"ID\": \"ASB-A-185125206\",\n \"CVE\": [\n \"CVE-2021-39698\"\n ],\n \"OSV\": \"https://osv.dev/vulnerability/ASB-A-185125206\",\n \"details\": [\n {\n \"unpatched_code\": \"fs/signalfd.c::signalfd_cleanup\",\n \"patch\": \"https://android.googlesource.com/kernel/common/+/9537bae0da1f\",\n \"matched_signature\": \"ASB-A-185125206-c9d43168\"\n },\n {\n \"unpatched_code\": \"fs/signalfd.c\",\n \"patch\": \"https://android.googlesource.com/kernel/common/+/9537bae0da1f\",\n \"matched_signature\": \"ASB-A-185125206-e8972c8a\"\n }\n ]\n }\n ]\n}\n\n```\n\nThe JSON report file presents the result in a key-value structure, where the\nmeaning of each key is as follows:\n\n\n<table>\n <thead>\n <tr>\n <th>Key</th>\n <th>Value</th>\n </tr>\n </thead>\n <tr>\n <td><strong><code>options</code></strong>\n </td>\n <td>Explicitly passed command options\n </td>\n </tr>\n <tr>\n <td><strong><code>covered_cves</code></strong>\n </td>\n <td>List of the CVEs covered by Vanir.\n </td>\n </tr>\n <tr>\n <td><strong><code>missing_patch</code></strong>\n </td>\n <td>A list of the detailed information of each unpatched CVE. <strong><code>ID</code></strong> is a unique ID of the vulnerability used in OSV, and <strong><code>CVE</code></strong> is a list of CVE aliases (most vulnerabilities have a single CVE entry). <strong><code>OSV</code></strong> is the public OSV URL of the vulnerability, which has more details of the vulnerability entry information if the CVE is not embargoed. <br/>\nThe <strong><code>details</code></strong> field is a list of unpatched code snippets in the following formats:\n\n<table>\n <tr>\n <td><strong><code>unpatched_code</code></strong>\n </td>\n <td>The relative path to the unpatched file and the function from the scanned target root.\n </td>\n </tr>\n <tr>\n <td><strong><code>patch</code></strong>\n </td>\n <td>The public URL to the patch that should be applied.\n </td>\n </tr>\n <tr>\n <td><strong><code>matched_signature</code></strong>\n </td>\n <td>The unique ID of the matched signature. The details can be found from the <strong><code>$VUL_FILE</code></strong> passed to the detector.\n </td>\n </tr>\n</table>\n\n\n </td>\n </tr>\n</table>\n\nThe HTML report file shows the same result in a more human-readable format as\nfollows:\n\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Vanir is a source code-based static analysis tool that automatically identifies the list of missing security patches in the target system. ",
"version": "1.0.1",
"project_urls": {
"Homepage": "https://github.com/google/vanir",
"Issues": "https://github.com/google/vanir/issues"
},
"split_keywords": [
"static analysis",
" source code analysis",
" missing patch scanner"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "0e94d45d2f9c03ab0dbccf20f6f4addb11b9c0510929cc0bf00b57464151655b",
"md5": "39b8ea6961af8cba3f2f0b050661f064",
"sha256": "697c47aeee0c4f296f79cf439394ca726c830e21fae4afe489f21d5aa2369809"
},
"downloads": -1,
"filename": "vanir-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "39b8ea6961af8cba3f2f0b050661f064",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.14,>=3.9",
"size": 13685630,
"upload_time": "2025-08-13T06:50:38",
"upload_time_iso_8601": "2025-08-13T06:50:38.555262Z",
"url": "https://files.pythonhosted.org/packages/0e/94/d45d2f9c03ab0dbccf20f6f4addb11b9c0510929cc0bf00b57464151655b/vanir-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4815f920cb312f172835a6d2770fc3b0d77b4b14b11ff4d8ff0dbc6850828485",
"md5": "251dae58c22b1ce291a07029fb0374b0",
"sha256": "e1bd2050a9091473e3d705f8146044ffd221b086bf465544775030a0f236d78b"
},
"downloads": -1,
"filename": "vanir-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "251dae58c22b1ce291a07029fb0374b0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.14,>=3.9",
"size": 13549471,
"upload_time": "2025-08-13T06:50:41",
"upload_time_iso_8601": "2025-08-13T06:50:41.259312Z",
"url": "https://files.pythonhosted.org/packages/48/15/f920cb312f172835a6d2770fc3b0d77b4b14b11ff4d8ff0dbc6850828485/vanir-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 06:50:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "google",
"github_project": "vanir",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "requests",
"specs": []
},
{
"name": "absl-py",
"specs": []
},
{
"name": "mmh3",
"specs": []
},
{
"name": "unidiff",
"specs": []
},
{
"name": "jinja2",
"specs": []
},
{
"name": "typing_extensions",
"specs": [
[
">=",
"4"
],
[
"<",
"5"
]
]
},
{
"name": "python-dateutil",
"specs": []
},
{
"name": "tenacity",
"specs": []
},
{
"name": "six",
"specs": []
},
{
"name": "ply",
"specs": []
},
{
"name": "decorator",
"specs": []
}
],
"lcname": "vanir"
}