Advanced SAST C/C++ の設定
- プラン: Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
はじめに
パイプラインでアナライザーを実行するには、SASTテンプレートを含め、GitLab高度なSASTを有効にします:
include:
- template: Jobs/SAST.gitlab-ci.yml
variables:
GITLAB_ADVANCED_SAST_CPP_ENABLED: "true"
SAST_COMPILATION_DATABASE: "compile_commands.json"または、SASTコンポーネントを使用します:
include:
- component: gitlab.com/components/sast/sast@main
inputs:
run_advanced_sast_cpp: "true"
variables:
SAST_COMPILATION_DATABASE: "compile_commands.json"この最小限の設定では、プロジェクトがコンパイルデータベース(CDB)を生成できることを前提としています。次のセクションでは、その作成方法について説明します。
前提条件
GitLab高度なSAST CPPアナライザーは、ソースファイルを正しく解析および分析するために、コンパイルデータベース(CDB)を必要とします。
CDBは、各変換ユニットのエントリを1つ含むJSONファイル(compile_commands.json)です。通常、各エントリは以下を指定します:
- ファイルのビルドに使用されるコンパイラコマンド
- コンパイラフラグとインクルードパス
- コンパイルが実行される作業ディレクトリ
CDBを使用すると、アナライザーは正確なビルド環境を再現し、正確な解析中とセマンティック分析を保証できます。
CDBを作成
CDBの生成方法は、ビルドシステムによって異なります。以下に一般的な例を示します。
例: CMake
CMakeは、-DCMAKE_EXPORT_COMPILE_COMMANDS=ONパラメータをcmake呼び出しに追加することにより、CDBを直接生成できます:
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ONこのオプションは、プロジェクトを構成し、compile_commands.jsonファイルをbuildフォルダーに生成します。これは、各ソースファイルのコンパイラコマンドを記録します。
GitLab高度なSAST CPPアナライザーは、このファイルに依存して、ビルド環境を正確に再現します。
生成されたcompile_commands.jsonファイルを、次のビルドジョブの例のジョブアーティファクトとしてエクスポートします:
<YOUR-BUILD-JOB-NAME>:
image: ubuntu:24.04
before_script:
- apt update -qq && apt install -y -qq cmake build-essential
script:
- mkdir -p build
- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- make -j$(nproc)
artifacts:
paths:
- build/compile_commands.json # Pass the CDB file to the gitlab-advanced-sast-cpp jobさまざまなビルドシステムの例
CDBを作成し、さまざまなビルドシステムでGitLab高度なSAST CPPを実行する完全な例もあります:
アナライザーにCDBを提供する
SAST_COMPILATION_DATABASE変数を使用して、GitLab高度なSAST CPPアナライザーにCDBの場所を指示します:
variables:
SAST_COMPILATION_DATABASE: YOUR_COMPILATION_DATABASE.jsonSAST_COMPILATION_DATABASEが指定されていない場合、GitLab高度なSAST CPPアナライザーは、デフォルトでプロジェクトルートディレクトリにあるcompile_commands.jsonという名前のファイルを使用します。
compile_commands.jsonファイルを生成するビルドジョブは、gitlab-advanced-sast-cppジョブが使用するために、ジョブアーティファクトとしてエクスポートする必要があります:
variables:
SAST_COMPILATION_DATABASE: build/compile_commands.json
<YOUR-BUILD-JOB-NAME>:
image: ubuntu:24.04
before_script:
- apt update -qq && apt install -y -qq cmake build-essential
script:
- mkdir -p build
- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- make -j$(nproc)
artifacts:
paths:
- build/compile_commands.json # Pass the CDB file to the gitlab-advanced-sast-cpp jobまたは、CDBのキャッシュをレビューします。
最適化: 効率性のための並列実行
CDBを複数のパーティションに分割することにより、アナライザーを並列実行できます。GitLab Advanced SAST CPPリポジトリは、これに役立つヘルパースクリプトを提供します。
スクリプトを含めます:
include: - project: "gitlab-org/security-products/demos/sast/gitlab-advanced-sast-cpp-templates" file: "templates/scripts.yml"ヘルパースクリプトを参照して、ビルドジョブでCDBを分割します:
<YOUR-BUILD-JOB-NAME>: script: - <your-script to generate the CDB> - !reference [.gitlab-advanced-sast-cpp-scripts] - split_cdb "${BUILD_DIR}" 1 4 # Split into 4 fragments artifacts: paths: - ${BUILD_DIR} # Pass the split CDB files to the parallelized gitlab-advanced-sast-cpp jobssplit_cdbは、${BUILD_DIR}/compile_commands.jsonを読み取るようにハードコードされています。split_cdbを呼び出す前に、ビルドがこの正確な場所にCDBを生成することを確認してください。並列アナライザージョブを実行します:
gitlab-advanced-sast-cpp: parallel: 4 variables: SAST_COMPILATION_DATABASE: "${BUILD_DIR}/compile_commands${CI_NODE_INDEX}.json" needs: - job: <YOUR-BUILD-JOB-NAME> artifacts: trueparallel: 4は、4つのジョブにわたって実行をシャードします。${CI_NODE_INDEX}(1、2、3、4)は、正しいCDBフラグメントを選択します。needsは、アナライザージョブがビルドジョブによって生成されたアーティファクトを受信することを保証します。
この設定では、ビルドジョブは1つのcompile_commands.jsonを生成します。split_cdbスクリプトは複数のパーティションを作成し、アナライザージョブは並列実行され、各ジョブが1つのパーティションを処理します。
ルールセットの設定
GitLab高度なSAST CPPは、カスタムルールセットをサポートします。ここで、「ルール」はGitLab高度なSAST CPPチェッカーです。
カスタムルールセットは、パススルー (CodeChecker設定ファイルで構成される)で作成できます。
パススルー設定は、次のように処理されます:
targetDirとtargetは無視されます。パススルーを処理した後、結果のフラグはCodeCheckerに直接渡されますoverwriteモードは設定全体を置き換え、appendモードはフラグを追加します- 特定の
CodeCheckerフラグはカスタマイズできません。アナライザーフラグ-o、--output、および解析フラグ-o, --output, -e, --exportなどです serverとstoreの設定項目は無視されます
たとえば、次の.gitlab/sastconfig.tomlがあるとします:
[gitlab-advanced-sast-cpp]
description = "My ruleset"
[[gitlab-advanced-sast-cpp.passthrough]]
# replace the GitLab default configuration with my own
mode = "overwrite"
type = "url"
value = "https://example.com/gitlab-advanced-sast-cpp.yaml"
[[gitlab-advanced-sast-cpp.passthrough]]
# append flags from a file in the current repository
mode = "append"
type = "file"
value = "gitlab-advanced-sast-cpp.yml"次のコンテンツがhttps://example.com/gitlab-advanced-sast-cpp.yamlにあるとします:
analyzer:
- --disable-all
- --enable=core.DivideZeroおよびgitlab-advanced-sast-cpp.ymlを含む:
analyzer:
- --enable=core.CallAndMessage有効な結果の設定は次のようになります:
analyzer:
- --disable-all
- --enable=core.DivideZero
- --enable=core.CallAndMessageトラブルシューティング
cdb-rebaseを使用したパスのリベース
CDB内のパスがCI/CDジョブのコンテナパスと一致しない場合は、cdb-rebaseで調整します。
インストール:
go install gitlab.com/gitlab-org/secure/tools/cdb-rebase@latestバイナリは$GOPATH/binまたは$HOME/go/binにインストールされます。このディレクトリがPATHにあることを確認してください。
使用例:
cdb-rebase compile_commands.json /host/path /container/path > rebased_compile_commands.jsonCDBを修正する
ビルド環境がスキャン環境と異なる場合、生成されたCDBの調整が必要になる場合があります。jqを使用して変更するか、事前定義されたヘルパースクリプトのシェル関数であるcdb_appendを使用します。
cdb_appendは、コンパイラオプションを既存のCDBに追加します。以下を受け入れます:
- 最初の引数:
compile_commands.jsonを含むフォルダー - 後続の引数: 追加する追加のコンパイラオプション
CI/CDの例:
include:
- project: "gitlab-org/security-products/demos/sast/gitlab-advanced-sast-cpp-templates"
file: "templates/scripts.yml"
<YOUR-BUILD-JOB-NAME>:
script:
- !reference [.gitlab-advanced-sast-cpp-scripts]
- <your-script to generate the CDB>
- cdb_append "${BUILD_DIR}" "-I'$PWD/include-cache'" "-Wno-error=register"CDBをキャッシュする
コンパイルと分析の処理を高速化するために、CDBをキャッシュできます。
.cdb_cache:
cache: &cdb_cache
key:
files:
- Makefile
- src/
paths:
- compile_commands.json
<YOUR-BUILD-JOB-NAME>:
script:
- <your-script to generate the CDB>
cache:
<<: *cdb_cache
policy: pull-push
gitlab-advanced-sast-cpp:
cache:
<<: *cdb_cache
policy: pull完全な例については、デモプロジェクトcached-cdbを参照してください。
CDB内の絶対パスを処理する
デモプロジェクトでは、bearはDockerジョブのビルドディレクトリから実行されます。CDBのパスは絶対パスであり、/builds/$CI_PROJECT_PATHに基づいています。アナライザージョブgitlab-advanced-sast-cppは同じ場所で実行されるため、パスは正しいです。
スキャン中にCDBが利用できないパスで生成された場合は、リベースする必要があります。アナライザーイメージに含まれているcdb-rebaseツールは、directory、file、およびoutputパスを書き換えます。
例:
gitlab-advanced-sast-cpp:
before-script:
# Rebase the original CDB to be relative to the current directory.
#
# ORIGINAL_CDB_PATH - Path to the CDB artifact from a previous job (e.g., artifacts/compile_commands.json)
# ORIGINAL_CDB_BASEPATH - The absolute path to the project root when the ORIGINAL_CDB_PATH was generated.
# (e.g., /mnt/custom_build_area/my-project or /home/user/my-project)
- /cdb-rebase --input "$ORIGINAL_CDB_PATH" \
--output compile_commands.json \
--src "$ORIGINAL_CDB_BASEPATH" \
--dst .完全なデモンストレーションについては、cdb-rebase-demoを参照してください
単純なパスのリベースを超えて、cdb-rebaseはビルド環境とスキャン環境の間でインクルードファイルを管理することもできます:
- 外部ヘッダーをキャッシュします:
--include-cacheを使用すると、ソースツリーの外部にあるヘッダーはポータブルキャッシュにコピーされます。 - インクルードパスを追加する:
--includeを使用すると、キャッシュする追加のインクルードディレクトリを指定します。 - ファイルを除外する:
--excludeを使用すると、引き継ぎたくないヘッダーをスキップします。
例:
/cdb-rebase --src /my-project \
--dst /scan-env \
--input build/compile_commands.json \
--output rebased_cdb.json \
--include-cache include-cache \
--include third_party/include \
--exclude dummy.hcde-rebaseツールはGoがインストールされている環境でも使用できるため、生成時にCDBをリベースすることができます(例:
go install gitlab.com/gitlab-org/security-products/analyzers/clangsa/cmd/cdb-rebase@latest
bear -o compile_commands_abs.json -- make
cdb-rebase -i compile_commands_abs.json -o compile_commands.json -s "$PWD" -d .注: 上記のgo installコマンドは、cdb-rebaseをGOBINパスにインストールします。これは、go env GOBINで確認できます。
ヘッダーファイルがないために、スキャンのカバレッジが部分的になる
スキャンジョブで必要なシステムまたはサードパーティのヘッダーファイルが使用できない場合、スキャンのカバレッジが部分的になることがあります。ビルドジョブ中にインストールされたヘッダーは、明示的にスキャンジョブに転送し、コンパイルデータベースに記録されているインクルードパスを介して解決できるようにする必要があります。
一般的な方法の1つは、必要なヘッダーをキャッシュし、コンパイルデータベースを更新してそれらを参照することです:
# Create and populate an include cache
mkdir -p include-cache
dpkg -L <build-dependency-packages> | sed -n 's:^/usr/include/::p' > headers.txt
rsync -a --files-from=headers.txt /usr/include/ include-cache/
# Add cached headers to compile flags
cdb_append . "-I'$PWD/include-cache'"完全なデモンストレーションについては、例を参照してください。