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

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

SAST_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リポジトリは、これに役立つヘルパースクリプトを提供します。

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

    include:
      - project: "gitlab-org/security-products/demos/sast/gitlab-advanced-sast-cpp-templates"
        file: "templates/scripts.yml"
  2. ヘルパースクリプトを参照して、ビルドジョブで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 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は、アナライザージョブがビルドジョブによって生成されたアーティファクトを受信することを保証します。

この設定では、ビルドジョブは1つのcompile_commands.jsonを生成します。split_cdbスクリプトは複数のパーティションを作成し、アナライザージョブは並列実行され、各ジョブが1つのパーティションを処理します。

ルールセットの設定

GitLab高度なSAST CPPは、カスタムルールセットをサポートします。ここで、「ルール」はGitLab高度なSAST CPPチェッカーです。

カスタムルールセットは、パススルーCodeChecker設定ファイルで構成される)で作成できます。

パススルー設定は、次のように処理されます:

  • targetDirtargetは無視されます。パススルーを処理した後、結果のフラグはCodeCheckerに直接渡されます
  • overwriteモードは設定全体を置き換え、appendモードはフラグを追加します
  • 特定のCodeCheckerフラグはカスタマイズできません。アナライザーフラグ-o--output、および解析フラグ-o, --output, -e, --exportなどです
  • serverstoreの設定項目は無視されます

たとえば、次の.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.json

CDBを修正する

ビルド環境がスキャン環境と異なる場合、生成された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ツールは、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-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.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で確認できます。

ヘッダーファイルがないために、スキャンのカバレッジが部分的になる

スキャンジョブで必要なシステムまたはサードパーティのヘッダーファイルが使用できない場合、スキャンのカバレッジが部分的になることがあります。ビルドジョブ中にインストールされたヘッダーは、明示的にスキャンジョブに転送し、コンパイルデータベースに記録されているインクルードパスを介して解決できるようにする必要があります。

一般的な方法の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'"

完全なデモンストレーションについては、を参照してください。