VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/CodeQL/Readme.md

Last change on this file was 105670, checked in by vboxsync, 9 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • Property svn:eol-style set to native
File size: 19.8 KB
Line 
1# CodeQL Plugin
2
3The set of CodeQL plugins provided include two main plugins that seamlessly integrate into a Stuart build environment:
4
51. `CodeQlBuildPlugin` - Used to produce a CodeQL database from a build.
62. `CodeQlAnalyzePlugin` - Used to analyze a CodeQL database.
7
8While CodeQL can be run in a CI environment with other approaches. This plugin offers the following advantages:
9
101. Provides exactly the same results locally as on a CI server.
112. Integrates very well into VS Code.
123. Very simple to use - just use normal Stuart update and build commands.
134. Very simple to understand - minimally wraps the official CodeQL CLI.
145. Very simple to integrate - works like any other Stuart build plugin.
15 - Integration is usually just a few lines of code.
166. Portable - not tied to Azure DevOps specific, GitHub specific, or other host infrastructure.
177. Versioned - the query and filters are versioned in source control so easy to find and track.
18
19It is very important to read the Integration Instructions in this file and determine how to best integrate the
20CodeQL plugin into your environment.
21
22Due to the total size of dependencies required to run CodeQL and the flexibility needed by a platform to determine what
23CodeQL queries to run and how to interpret results, a number of configuration options are provided to allow a high
24degree of flexibility during platform integration.
25
26This document is focused on those setting up the CodeQL plugin in their environment. Once setup, end users simply need
27to use their normal build commands and process and CodeQL will be integrated with it. The most relevant section for
28such users is [Local Development Tips](#local-development-tips).
29
30## Table of Contents
31
321. [Database and Analysis Result Locations](#database-and-analysis-result-locations)
332. [Global Configuration](#global-configuration)
343. [Package-Specific Configuration](#package-specific-configuration)
354. [Filter Patterns](#filter-patterns)
365. [Integration Instructions](#integration-instructions)
37 - [Integration Step 1 - Choose Scopes](#integration-step-1---choose-scopes)
38 - [Scopes Available](#scopes-available)
39 - [Integration Step 2 - Choose CodeQL Queries](#integration-step-2---choose-codeql-queries)
40 - [Integration Step 3 - Determine Global Configuration Values](#integration-step-3---determine-global-configuration-values)
41 - [Integration Step 4 - Determine Package-Specific Configuration Values](#integration-step-4---determine-package-specific-configuration-values)
42 - [Integration Step 5 - Testing](#integration-step-5---testing)
43 - [Integration Step 6 - Define Inclusion and Exclusion Filter Patterns](#integration-step-6---define-inclusion-and-exclusion-filter-patterns)
446. [High-Level Operation](#high-level-operation)
45 - [CodeQlBuildPlugin](#codeqlbuildplugin)
46 - [CodeQlAnalyzePlugin](#codeqlanalyzeplugin)
477. [Local Development Tips](#local-development-tips)
488. [Resolution Guidelines](#resolution-guidelines)
49
50## Database and Analysis Result Locations
51
52The CodeQL database is written to a directory unique to the package and target being built:
53
54 `Build/codeql-db-<package>-<target>-<instance>`
55
56For example: `Build/codeql-db-mdemodulepkg-debug-0`
57
58The plugin does not delete or overwrite existing databases, the instance value is simply increased. This is
59because databases are large, take a long time to generate, and are important for reproducing analysis results. The user
60is responsible for deleting database directories when they are no longer needed.
61
62Similarly, analysis results are written to a directory unique to the package and target. For analysis, results are
63stored in individual files so those files are stored in a single directory.
64
65For example, all analysis results for the above package and target will be stored in:
66 `codeql-analysis-mdemodulepkg-debug`
67
68CodeQL results are stored in [SARIF](https://sarifweb.azurewebsites.net/) (Static Analysis Results Interchange Format)
69([CodeQL SARIF documentation](https://codeql.github.com/docs/codeql-cli/sarif-output/)) files. Each SARIF file
70corresponding to a database will be stored in a file with an instance matching the database instance.
71
72For example, the analysis result file for the above database would be stored in this file:
73 `codeql-analysis-mdemodulepkg-debug/codeql-db-mdemodulepkg-debug-0.sarif`
74
75Result files are overwritten. This is because result files are quick to generate and need to represent the latest
76results for the last analysis operation performed. The user is responsible for backing up SARIF result files if they
77need to saved.
78
79## Global Configuration
80
81Global configuration values are specified with build environment variables.
82
83These values are all optional. They provide a convenient mechanism for a build script to set the value for all packages
84built by the script.
85
86- `STUART_CODEQL_AUDIT_ONLY` - If `true` (case insensitive), `CodeQlAnalyzePlugin` will be in audit-only mode. In this
87 mode all CodeQL failures are ignored.
88- `STUART_CODEQL_PATH` - The path to the CodeQL CLI application to use.
89- `STUART_CODEQL_QUERY_SPECIFIERS` - The CodeQL CLI query specifiers to use. See [Running codeql database analyze](https://codeql.github.com/docs/codeql-cli/analyzing-databases-with-the-codeql-cli/#running-codeql-database-analyze)
90 for possible options.
91- `STUART_CODEQL_FILTER_FILES` - The path to "filter" files that contains filter patterns as described in
92 [Filter Patterns](#filter-patterns).
93 - More than one file may be specified by separating each absolute file path with a comma.
94 - This might be useful to reference a global filter file from an upstream repo and also include a global filter
95 file for the local repo.
96 - Filters are concatenated in the order of files in the variable. Patterns in later files can override patterns
97 in earlier files.
98 - The file only needs to contain a list of filter pattern strings under a `"Filters"` key. For example:
99
100 ```yaml
101 {
102 "Filters": [
103 "<pattern-line-1>",
104 "<pattern-line-2>"
105 ]
106 }
107 ...
108 ```
109
110 Comments are allowed in the filter files and begin with `#` (like a normal YAML file).
111
112## Package-Specific Configuration
113
114Package-specific configuration values reuse existing package-level configuration approaches to simplify adjusting
115CodeQL plugin behavior per package.
116
117These values are all optional. They provide a convenient mechanism for a package owner to adjust settings specific to
118the package.
119
120``` yaml
121 "CodeQlAnalyze": {
122 "AuditOnly": False, # Don't fail the build if there are errors. Just log them.
123 "QuerySpecifiers": "" # Query specifiers to pass to CodeQL CLI.
124 "Filters": "" # Inclusion/exclusion filters
125 }
126```
127
128> _NOTE:_ If a global filter set is provided via `STUART_CODEQL_FILTER_FILES` and a package has a package-specific
129> list, then the package-specific filter list (in a package CI YAML file) is appended onto the global filter list and
130> may be used to override settings in the global list.
131
132The format used to specify items in `"Filters"` is specified in [Filter Patterns](#filter-patterns).
133
134## Filter Patterns
135
136As you inspect results, you may want to include or exclude certain sets of results. For example, exclude some files by
137file path entirely or adjust the CodeQL rule applied to a certain file. This plugin reuses logic from a popular
138GitHub Action called [`filter-sarif`](https://github.com/advanced-security/filter-sarif) to allow filtering as part of
139the plugin analysis process.
140
141If any results are excluded using filters, the results are removed from the SARIF file. This allows the exclude results
142seen locally to exactly match the results on the CI server.
143
144Read the ["Patterns"](https://github.com/advanced-security/filter-sarif#patterns) section there for more details. The
145patterns section is also copied below with some updates to make the information more relevant for an edk2 codebase
146for convenience.
147
148Each pattern line is of the form:
149
150```plaintext
151[+/-]<file pattern>[:<rule pattern>]
152```
153
154For example:
155
156```yaml
157-**/*Test*.c:** # exclusion pattern: remove all alerts from all test files
158-**/*Test*.c # ditto, short form of the line above
159+**/*.c:cpp/infiniteloop # inclusion pattern: This line has precedence over the first two
160 # and thus "allow lists" alerts of type "cpp/infiniteloop"
161**/*.c:cpp/infiniteloop # ditto, the "+" in inclusion patterns is optional
162** # allow all alerts in all files (reverses all previous lines)
163```
164
165- The path separator character in patterns is always `/`, independent of the platform the code is running on and
166 independent of the paths in the SARIF file.
167- `*` matches any character, except a path separator
168- `**` matches any character and is only allowed between path separators, e.g. `/**/file.txt`, `**/file.txt` or `**`.
169 NOT allowed: `**.txt`, `/etc**`
170- The rule pattern is optional. If omitted, it will apply to alerts of all types.
171- Subsequent lines override earlier ones. By default all alerts are included.
172- If you need to use the literals `+`, `-`, `\` or `:` in your pattern, you can escape them with `\`, e.g.
173 `\-this/is/an/inclusion/file/pattern\:with-a-semicolon:and/a/rule/pattern/with/a/\\/backslash`. For `+` and `-`, this
174 is only necessary if they appear at the beginning of the pattern line.
175
176## Integration Instructions
177
178First, note that most CodeQL CLI operations will take a long time the first time they are run. This is due to:
179
1801. Downloads - Downloading the CodeQL CLI binary (during `stuart_update`) and downloading CodeQL queries during
181 CodeQL plugin execution
1822. Cache not established - CodeQL CLI caches data as it performs analysis. The first time analysis is performed will
183 take more time than in the future.
184
185Second, these are build plugins. This means a build needs to take place for the plugins to run. This typically happens
186in the following two scenarios:
187
1881. `stuart_build` - A single package is built and the build process is started by the stuart tools.
1892. `stuart_ci_build` - A number of packages may be built and the build process is started by the `CompilerPlugin`.
190
191In any case, each time a package is built, the CodeQL plugins will be run if their scopes are active.
192
193### Integration Step 1 - Choose Scopes
194
195Decide which scopes need to be enabled in your platform, see [Scopes Available](#scopes-available).
196
197Consider using a build profile to enable CodeQL so developers and pipelines can use the profile when they are
198interested in CodeQL results but in other cases they can easily work without CodeQL in the way.
199
200Furthermore, build-script specific command-line parameters might be useful to control CodeQL scopes and other
201behavior.
202
203#### Scopes Available
204
205This CodeQL plugin leverages scopes to control major pieces of functionality. Any combination of scopes can be
206returned from the `GetActiveScopes()` function in the platform settings manager to add and remove functionality.
207
208Plugin scopes:
209
210- `codeql-analyze` - Activate `CodeQlAnalyzePlugin` to perform post-build analysis of the last generated database for
211 the package and target specified.
212- `codeql-build` - Activate `CodeQlBuildPlugin` to hook the firmware build in pre-build such that the build will
213 generate a CodeQL database during build.
214
215In most cases, to perform a full CodeQL run, `codeql-build` should be enabled so a new CodeQL database is generated
216during build and `codeql-analyze` should be be enabled so analysis of that database is performed after the build is
217completed.
218
219External dependency scopes:
220
221- `codeql-ext-dep` - Downloads the cross-platform CodeQL CLI as an external dependency.
222- `codeql-linux-ext-dep` - Downloads the Linux CodeQL CLI as an external dependency.
223- `codeql-windows-ext-dep` - Downloads the Windows CodeQL CLI as an external dependency.
224
225Note, that the CodeQL CLI is large in size. Sizes as of the [v2.11.2 release](https://github.com/github/codeql-cli-binaries/releases/tag/v2.11.2).
226
227| Cross-platform | Linux | Windows |
228|:--------------:|:------:|:-------:|
229| 934 MB | 415 MB | 290 MB |
230
231Therefore, the following is recommended:
232
2331. **Ideal** - Create container images for build agents and install the CodeQL CLI for the container OS into the
234 container.
2352. Leverage host-OS detection (e.g. [`GetHostInfo()`](https://github.com/tianocore/edk2-pytool-library/blob/42ad6561af73ba34564f1577f64f7dbaf1d0a5a2/edk2toollib/utility_functions.py#L112))
236to set the scope for the appropriate operating system. This will download the much smaller OS-specific application.
237
238> _NOTE:_ You should never have more than one CodeQL external dependency scope enabled at a time.
239
240### Integration Step 2 - Choose CodeQL Queries
241
242Determine which queries need to be run against packages in your repo. In most cases, the same set of queries will be
243run against all packages. It is also possible to customize the queries run at the package level.
244
245The default set of Project Mu CodeQL queries is specified in the `MuCodeQlQueries.qls` file in this plugin.
246
247> _NOTE:_ The queries in `MuCodeQlQueries.qls` may change at any time. If you do not want these changes to impact
248> your platform, do not relay on option (3).
249
250The plugin decides what queries to run based on the following, in order of preference:
251
2521. Package CI YAML file query specifier
2532. Build environment variable query specifier
2543. Plugin default query set file
255
256For details on how to set (1) and (2), see the Package CI Configuration and Environment Variable sections respectively.
257
258> _NOTE:_ The value specified is directly passed as a `query specifier` to CodeQL CLI. Therefore, the arguments
259> allowed by the `<query-specifiers>` argument of CodeQL CLI are allowed here. See
260> [Running codeql database analyze](https://codeql.github.com/docs/codeql-cli/analyzing-databases-with-the-codeql-cli/#running-codeql-database-analyze).
261
262A likely scenario is that a platform needs to run local/closed source queries in addition to the open-source queries.
263There's various ways to handle that:
264
2651. Create a query specifier that includes all the queries needed, both public and private and use that query specifier,
266 either globally or at package-level.
267
268 For example, at the global level - `STUART_CODEQL_QUERY_SPECIFIERS` = _"Absolute_path_to_AllMyQueries.qls"_
269
2702. Specify a query specifier that includes the closed sources queries and reuse the public query list provided by
271 this plugin.
272
273 For example, at the global level - `STUART_CODEQL_QUERY_SPECIFIERS` = _"Absolute_path_to_MuCodeQlQueries.qls
274 Absolute_path_to_ClosedSourceQueries.qls"_
275
276Refer to the CodeQL documentation noted above on query specifiers to devise other options.
277
278### Integration Step 3 - Determine Global Configuration Values
279
280Review the Environment Variable section to determine which, if any, global values need to be set in your build script.
281
282### Integration Step 4 - Determine Package-Specific Configuration Values
283
284Review the Package CI Configuration section to determine which, if any, global values need to be set in your
285package's CI YAML file.
286
287### Integration Step 5 - Testing
288
289Verify a `stuart_update` and `stuart_build` (or `stuart_ci_build`) command work.
290
291### Integration Step 6 - Define Inclusion and Exclusion Filter Patterns
292
293After reviewing the test results from Step 5, determine if you need to apply any filters as described in
294[Filter Patterns](#filter-patterns).
295
296## High-Level Operation
297
298This section summarizes the complete CodeQL plugin flow. This is to help developers understand basic theory of
299operation behind the plugin and can be skipped by anyone not interested in those details.
300
301### CodeQlBuildPlugin
302
3031. Register a pre-build hook
3042. Determine the package and target being built
3053. Determine the best CodeQL CLI path to use
306 - First choice, the `STUART_CODEQL_PATH` environment variable
307 - Note: This is set by the CodeQL CLI external dependency if that is used
308 - Second choice, `codeql` as found on the system path
3094. Determine the directory name for the CodeQL database
310 - Format: `Build/codeql-db-<package>-<target>-<instance>`
3115. Clean the build directory of the active platform and target
312 - CodeQL database generation only works on clean builds
3136. Ensure the "build" step is not skipped as a build is needed to generate a CodeQL database
3147. Build a CodeQL file that wraps around the edk2 build
315 - Written to the package build directory
316 - Example: `Build/MdeModulePkg/VS2022/codeql_build_command.bat`
3178. Set the variables necessary for stuart to call CodeQL CLI during the build phase
318 - Sets `EDK_BUILD_CMD` and `EDK_BUILD_PARAMS`
319
320### CodeQlAnalyzePlugin
321
3221. Register a post-build hook
3232. Determine the package and target being built
3243. Determine the best CodeQL CLI path to use
325 - First choice, the `STUART_CODEQL_PATH` environment variable
326 - Note: This is set by the CodeQL CLI external dependency if that is used
327 - Second choice, `codeql` as found on the system path
3284. Determine the directory name for the most recent CodeQL database
329 - Format: `Build/codeql-db-<package>-<target>-<instance>`
3305. Determine plugin audit status for the given package and target
331 - Check if `AuditOnly` is enabled either globally or for the package
3326. Determine the CodeQL query specifiers to use for the given package and target
333 - First choice, the package CI YAML file value
334 - Second choice, the `STUART_CODEQL_QUERY_SPECIFIERS`
335 - Third choice, use `CodeQlQueries.qls` (in the plugin directory)
3367. Run CodeQL CLI to perform database analysis
3378. Parse the analysis SARIF file to determine the number of CodeQL failures
3389. Return the number of failures (or zero if `AuditOnly` is enabled)
339
340## Local Development Tips
341
342This section contains helpful tips to expedite common scenarios when working with CodeQL locally.
343
3441. Pre-build, Build, and Post-Build
345
346 Generating a database requires the pre-build and build steps. Analyzing a database requires the post-build step.
347
348 Therefore, if you are making tweaks that don't affect the build, such as modifying the CodeQL queries used or level
349 of severity reported, you can save time by skipping pre-build and post-build (e.g. `--skipprebuild` and
350 `--skipbuild`).
351
3522. Scopes
353
354 Similar to (1), add/remove `codeql-build` and `codeql-analyze` from the active scopes to save time depending on what
355 you are trying to do.
356
357 If you are focusing on coding, remove the code CodeQL scopes if they are active. If you are ready to check your
358 changes against CodeQL, simply add the scopes back. It is recommended to use build profiles to do this more
359 conveniently.
360
361 If you already have CodeQL CLI enabled, you can remove the `codeql-ext-dep` scope locally. The build will use the
362 `codeql` command on your path.
363
3643. CodeQL Output is in the CI Build Log
365
366 To see exactly which queries CodeQL ran or why it might be taking longer than expected, look in the CI build log
367 (i.e. `Build/CI_BUILDLOG.txt`) where the CodeQL CLI application output is written.
368
369 Search for the text you see in the progress output (e.g. "Analyzing _MdeModulePkg_ (_DEBUG_) CodeQL database at")
370 to jump to the section of the log just before the CodeQL CLI is invoked.
371
3724. Use a SARIF Viewer to Read Results
373
374The [SARIF Viewer extension for VS Code](https://marketplace.visualstudio.com/items?itemName=MS-SarifVSCode.sarif-viewer)
375can open the .sarif file generated by this plugin and allow you to click links directly to the problem area in source
376files.
377
378## Resolution Guidelines
379
380This section captures brief guidelines to keep in mind while resolving CodeQL issues.
381
3821. Look at surrounding code. Changes should always take into account the context of nearby code. The new logic may
383 need to account conditions not immediately obvious based on the issue alone. It is easy to focus only on the line
384 of code highlighted by CodeQL and miss the code's role in the big picture.
3852. A CodeQL alert may be benign but the code can be refactored to prevent the alert. Often refactoring the code makes
386 the code intention clearer and avoids an unnecessary exception.
3873. Consider adding unit tests while making CodeQL fixes especially for commonly used code and code with a high volume
388 of CodeQL alerts.
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette