Advanced SAST C/C++ 設定
- プラン: Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
- ステータス: ベータ
はじめに
アナライザーをパイプラインで実行するには、SASTテンプレートを含め、GitLab Advanced 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
inputs:
run_advanced_sast_cpp: "true"
variables:
SAST_COMPILATION_DATABASE: "compile_commands.json"この最小限の設定は、プロジェクトがコンパイルデータベース(CDB)を生成できることを前提としています。次のセクションでは、その作成方法について説明します。
前提要件
GitLab Advanced SAST CPPアナライザーは、ソースファイルを正しく解析および分析するために、コンパイルデータベース(CDB)を必要とします。
CDBは、各翻訳単位に対して1つのエントリを含むJSONファイル(compile_commands.json)です。各エントリは通常、以下を指定します:
- ファイルのビルドに使用されるコンパイラコマンド
- コンパイラフラグとインクルードパス
- コンパイルが実行される作業ディレクトリ
CDBを使用すると、アナライザーは正確なビルド環境を再現し、正確な解析とセマンティック分析を保証できます。
CDBを作成する
CDBの生成方法は、ビルドシステムによって異なります。以下に一般的な例を示します。
例: CMake
CMakeは、-DCMAKE_EXPORT_COMPILE_COMMANDS=ONを使用してCDBを直接生成できます:
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ONこのオプションは、プロジェクトをビルドしません。各ソースファイルのコンパイラコマンドを記録するbuildフォルダーにcompile_commands.jsonファイルが生成されます。GitLab Advanced SAST CPPアナライザーは、このファイルを利用してビルド環境を正確に再現します。
さまざまなビルドシステムの例
CDBを作成し、GitLab Advanced SAST CPPをさまざまなビルドシステムで実行する完全な例もあります:
アナライザーにCDBを提供する
SAST_COMPILATION_DATABASE変数を使用して、GitLab Advanced SAST CPPアナライザーにCDBの場所を指示します:
variables:
SAST_COMPILATION_DATABASE: YOUR_COMPILATION_DATABASE.jsonSAST_COMPILATION_DATABASEが指定されていない場合、GitLab Advanced SAST CPPアナライザーは、プロジェクトルートにあるcompile_commands.json locatedという名前のファイルを使用することをデフォルトとします。
最適化: 効率性のための並列実行
CDBを複数のフラグメントに分割することにより、アナライザーを並列で実行できます。GitLab Advanced SAST CPPリポジトリは、このためのヘルパースクリプトを提供します。
スクリプトを含めます:
include: - project: "gitlab-org/security-products/analyzers/clangsa" file: "templates/scripts.yml"ヘルパースクリプトを参照し、ビルドジョブでCDBを分割します:
<YOUR-BUILD-JOB-NAME>: script: - <your-script to generate the CDB> - !reference [.clangsa-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は、アナライザージョブがビルドジョブによって生成されたアーティファクトを受信するようにします。
このセットアップでは、ビルドジョブは単一のcompile_commands.jsonを生成します。split_cdbスクリプトは複数のパーティションを作成し、アナライザージョブは並列で実行され、各ジョブが1つのパーティションを処理します。
トラブルシューティング
cdb-rebaseリベースパス
CDB内のパスがCIジョブのコンテナパスと一致しない場合は、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の例:
include:
- project: "gitlab-org/security-products/analyzers/clangsa"
file: "templates/scripts.yml"
<YOUR-BUILD-JOB-NAME>:
script:
- !reference [.clangsa-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–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で確認できます。