mcpField
C
chrome-release-verify

chrome-release-verify

github.com/electronセキュリティ123.6k46 回インストール今日更新
リポジトリ

chrome-release-verify について

Electron メンテナー向けに、Chrome のリリース修正をブランチに対応付け、パッチをローカルで検証してプルリクエストを準備するスキルです。提案したバックポートを進める前に、ユーザーの承認を求めます。

主な機能

  1. 01CVE と修正の対応付け
  2. 02ブランチ履歴による修正確認
  3. 03ローカルのバックポートパッチ作成
  4. 04パッチ競合の解決
  5. 05パッチの検査と再エクスポート
  6. 06バックポート用プルリクエスト作成

活用シーン

  1. 01Electron リリースブランチ向け Chrome 修正の評価
  2. 02適用可能なセキュリティ修正のバックポート
  3. 03プッシュ前のパッチ検証
  4. 04検証済みバックポート PR の準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/electron/electron --skill chrome-release-verify

インストール後、Claude Code で/chrome-release-verifyを入力して読み込まれたか確認します。

詳細

Chrome リリース → 検証済みバックポート PR

入力:$ARGUMENTS = <release-branch> <chrome-releases-blog-url>(例:41-x-y https://chromereleases.googleblog.com/2026/04/stable-channel-update-for-desktop_15.html)。どちらかが不足している場合は確認してください。

このフローはローカル優先です。すべてのパッチが e sync --3 で適用され、lint --patches に合格するまで、何もプッシュしません。

1. CVE → バグ → 修正 CL の対応付け

/chrome-release-cls <blog-url>(またはそのインライン手順)を実行して、/tmp/cve_bugs.txt(CVE|bug|severity|desc)と、バグごとの正規の修正 CL を作成します。各 CL について、repo(src/ 配下のパス:., v8, third_party/{skia,angle,pdfium,dawn}, third_party/libaom/source/libaom)と gerrit-host も記録してください。

ターゲットマイルストーンへのマージ CL が存在する場合は、それを優先してください(例:41-x-y が M146 に相当する場合、メイン CL より [M146] の cherry-pick を優先します)。すでにリベース済みで、競合する可能性がはるかに低いためです。Change-Id で git log --all --grep を実行するか、Gerrit の ?q=bug:<n> で探してください。Chrome がターゲットマイルストーンに修正をマージしていない場合でも、それだけを理由にスキップしてはいけません。Chrome のマージ期間は Electron のサポート期間より短いためです。メイン CL(または近隣マイルストーンへのリベース。手順 5 を参照)にフォールバックし、脆弱なコードがブランチに存在するかどうかは手順 3 で判断します。

2. 同期済みのワークツリーを準備する

e show configs に bp-<NN> があれば再利用し、なければ e worktree add bp-<NN> ~/src/electron-bp-<NN> --source <current> --no-sync を実行します。

cd <root>/src/electron
git fetch origin <branch>
git checkout -B security-backport/<branch>/<short-date> origin/<branch>
e use bp-<NN>
e sync 2>&1 | tee /tmp/bp_sync.log

同期に失敗し、NotADirectoryError: '<root>/src/.git/objects/info/alternates' が発生した場合は、bp 設定の env から GIT_CACHE_PATH を削除して再試行してください。

3. IN-TREE と NEEDS-BACKPORT を判定する

各バグについて、同期済みのリポジトリで次の 3 つを確認します。

  1. git -C "$repo" log HEAD --since='1 year ago' -E --grep="\b${bug}\b" --format='%h %s'
  2. Gerrit から Change-Id を取得し、git log HEAD --grep="^Change-Id: ${cid}$" を実行します。
  3. grep -rlE "(\b${bug}\b|${cid})" <root>/src/electron/patches/

いずれかでヒットした場合は IN-TREE です。すべて空の場合は NEEDS-BACKPORT です。

手順 1(または受け取った上流トリアージレポート)で RESTRICTED / 公開 CL なし とされた行は、引き継がれたものとして扱わず、ここで再調査してから分類してください。git -C "$repo" fetch origin と git -C "$repo" log --all --remotes -E --grep="(Bug|Fixed):.*\b${bug}\b" --format='%h %s' を実行し、chrome-release-cls スキルの gitiles_grep を chromium/src、v8、コンポーネントのリポジトリの refs/heads/main と branch-heads の参照に対して実行し、さらに Gerrit で ?q=bug:<id> / ?q=message:<id> を新たに検索してください。Gerrit の変更記録にはアクセス制限がかかっていても、修正コミットがすでに git で公開されていることはよくあります。また、実行中に制限が解除されることもあるため、以前の RESTRICTED 判定は手掛かりであって、結論ではありません。これらがすべて空の場合に限り、その行は RESTRICTED のままです。省略によって IN-TREE と判定してはいけません。人が後で確認できるよう、レポートに別途記載してください。

NEEDS-BACKPORT の各 CL について、ファイル一覧(/changes/<proj>~<cl>/revisions/current/files)も取得し、すべてのファイルが chrome/browser/、chrome/android/、ios/、または components/**/android/ 配下にある場合はスキップしてください。Electron ではこれらをコンパイルしません。

ここでテーブル(CVE | Sev | Bug | Component | Verdict | CL)と、提案するバックポート対象を報告し、続行前にユーザーの承認を得てください。

4. パッチをローカルに作成する(まだプッシュしない)

バックポートする各 CL について、raw パッチを取得し、patches/<dir>/ に書き込みます。

curl -s "https://${host}.googlesource.com/changes/${proj//\//%2F}~${cl}/revisions/current/patch" \
  | base64 -d > "patches/${dir}/cherry-pick-${short}.patch"
echo "cherry-pick-${short}.patch" >> "patches/${dir}/.patches"

Gerrit ホストが e cherry-pick でサポートされていないリポジトリ(例:aomedia 上の libaom)では、代わりに同期済みサブリポジトリの HEAD に対して上流コミットを git cherry-pick し、その結果を git format-patch してください。

新たに作成した patches/<dir>/ がある場合は、エントリごとに 1 行のコンパクトな形式を維持して patches/config.json に追記します。

  { "patch_dir": "src/electron/patches/<dir>", "repo": "src/third_party/<dir-or-nested-path>" }

5. e sync --3 で検証する

e sync --3 2>&1 | tee /tmp/bp_sync3.log

Patch failed at NNNN <subject> が表示された場合:

  • 失敗したリポジトリに cd し、git diff で競合マーカーを確認します。
  • テスト専用ファイル(例:web_tests/VirtualTestSuites、コンテキストのずれがある *_unittest.cc):セキュリティ関連のハンクが問題なくマージされていれば、ours を採用します(git checkout --ours -- <file>)。
  • 実質的なコードの競合:競合は、変更を取り下げる理由にはなりません。次の順に対応します。
    1. 対象マイルストーン上にある同じ Change-Id のマージ(Change-Id で git log --all --grep を実行するか、Gerrit で ?q=change:<Change-Id> を検索)に切り替えます。
    2. 近接するマイルストーン上にある同じ Change-Id(作者のリベース版。たとえば対象が M150 の場合は [M152] の CL でも構いません。ステータスが NEW でも問題ありません)と、修正が前提としている前提 CL(修正対象のヘルパーやシグネチャを導入したリファクタリング)を確認します。修正をそのまま適用できるものを選び、レポートに前提 CL を記載します。
    3. それ以外の場合は、修正の意味をブランチのコードに手動で移植します。対象リポジトリでハンクを解決して、ピックのパッチファイル内に反映し、ピックしたコミットに取り込みます(git commit --fixup と autosquash rebase を使用)。その後、再エクスポートします。上流コミットのヘッダーはそのまま保持し、パッチヘッダーに Electron adaptation notes (<branch>) の段落を追加して、すべての適応内容(メンバー名の変更、シグネチャの変更、ヘルパーのインライン化など)を記載します。機械的かつ構造的な変更のみを行い、修正が確認または保護する対象を絶対に変えず、上流の差分にない意味を決して作り出さないでください。その行を BACKPORTED (adapted) とし、レポートと PR 本文でレビュー担当者の注意を促します。適応したピックにも他と同じ基準が適用されます。e sync --3、lint --patches、および呼び出し元が要求するビルドゲートを通過させてください。
  • DROPPED にできるのは、次の 2 つの場合に限ります。(a) 脆弱性のあるコードがブランチに存在しない(ファイル、関数、機能が存在しない)、または (b) サブシステムの書き換えにより、修正を適用できる箇所がない。DROPPED とする各行には、該当する理由と証拠を記載します。取り下げたパッチは完全に削除してください(ファイルを削除し、.patches と config.json からも削除します)。
  • 解決後は、git add <files> && git -c commit.gpgsign=false am --continue を実行し、続けて e patches <repo> で解決済みパッチをエクスポートしてから、e sync --3 を再実行します。問題がなくなるまで繰り返します。

6. エクスポート → lint → 再適用のループ

e patches all
node script/lint.js --patches   # must exit 0

lint で指摘があった場合(通常は + で始まる行の末尾の空白)、修正するとパッチが書き込むバイト列が変わり、e patches が生成した index <old>..<new> のブロブハッシュが無効になります。.patch を手動で編集してそのままプッシュすると、ローカルでは lint に合格しても、CI の Apply Patches 再エクスポートチェックで index ハッシュの 1 行だけに差分が生じて失敗します。

そのため、エクスポート後に lint(または自分での編集)によって .patch ファイルを変更した場合は、もう一度ラウンドトリップしてください。

# fix the lint findings in patches/**/*.patch, then:
e sync            # re-apply the edited patches (no --3 needed; they applied cleanly last time)
e patches all     # re-export so index blob hashes match the edited content
node script/lint.js --patches      # must now exit 0
git diff --quiet -- patches/ || { echo "patches changed again — repeat the loop"; }

lint --patches が終了コード 0 を返し、最後の e patches all の後に git diff -- patches/ が空になるまで繰り返します。それで初めて、パッチセットが CI で安定した状態になります。

7. コミット、プッシュ、PR

git add patches/
git commit -m "chore: cherry-pick <N> changes from <dirs>"
git push origin HEAD
gh pr create --repo electron/electron --base <branch> --head <this-branch> \
  --title "chore: cherry-pick <N> changes from <dirs>" \
  --label "<branch>" --label backport-check-skip --label semver/patch --label "security 🔒" \
  --body-file /tmp/pr_body.md

PR の本文形式 — .github/PULL_REQUEST_TEMPLATE.md(Description of Change/Checklist/Release Notes セクション)に従ってください。形式に従っていない PR は自動的にクローズされます。

#### Description of Change

Backports the following changes:

* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject>
* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject> (adapted for <branch>; see patch header)
* ...

#### Checklist

- [x] I have filled out the PR description
- [x] [I have reviewed and verified the changes](https://github.com/electron/governance/blob/main/policy/ai.md)

#### Release Notes

Notes: Backported fixes from upstream Chromium and V8.

PR の本文では、セキュリティに関する表現を控えめにしてください。 PR は公開された時点で誰でも閲覧できますが、修正によってユーザーが保護されるのはリリース後です。その間にエクスプロイトの情報を広めないでください。具体的には、タイトル、本文、Notes: 行のいずれにも、CVE 番号、crbug.com へのリンク、「security」/「0-day」/深刻度を示す表現を含めないでください。security 🔒 ラベルは問題ありません(リリースの管理に使用します)。上流のコミットタイトルに「UAF」とあっても、そのまま記載してください。書き換えると、Gerrit CL との追跡可能性が損なわれます。含まれる修正内容に合うように Notes: の文言を調整してください(例:v8 のパッチがない場合は「and V8」を削除します)。

CVE と CL の対応関係は PR に記載しないでください。ローカルのメモファイル(/tmp/cve_cls.txt)に残し、理由とともに、修正内容を変更、削除、またはスキップしたものがあれば、それも含めてチャットでユーザーに報告してください。

作業が終わったら e use <previous> を復元してください。

コメント