正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

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.json

SAST_COMPILATION_DATABASEが指定されていない場合、GitLab Advanced SAST CPPアナライザーは、プロジェクトルートにあるcompile_commands.json locatedという名前のファイルを使用することをデフォルトとします。

最適化: 効率性のための並列実行

CDBを複数のフラグメントに分割することにより、アナライザーを並列で実行できます。GitLab Advanced SAST CPPリポジトリは、このためのヘルパースクリプトを提供します。

  1. スクリプトを含めます:

    include:
      - project: "gitlab-org/security-products/analyzers/clangsa"
        file: "templates/scripts.yml"
  2. ヘルパースクリプトを参照し、ビルドジョブで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 jobs

    split_cdbは、${BUILD_DIR}/compile_commands.jsonを読み取るようにハードコードされています。split_cdbを呼び出す前に、ビルドでこの正確な場所にCDBが生成されるようにしてください。

  3. 並列アナライザージョブを実行します:

    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: true
    • parallel: 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.json

CDBの修正

ビルド環境がスキャン環境と異なる場合、生成された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ツールは、directoryfile、および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.h

cde-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-rebaseGOBINパスにインストールします。これは、go env GOBINで確認できます。