Amazon Linux 2023 の公式 SRPM から PHP 8.2.35 を CodeBuild でビルドしてみた

Amazon Linux 2023 の公式 SRPM から PHP 8.2.35 を CodeBuild でビルドしてみた

PHP の重大な脆弱性に対し、公式パッチが出るまでの間、AL2023 公式の SRPM をベースにソースだけを差し替えて修正版 RPM を自作する手順を紹介します。CodeBuild を使ったビルドからサーバーへの適用まで、実際に試した方法をまとめました。
2026.10.22

はじめに

梶原@福岡オフィスです。
PHP の重大な脆弱性 2 件が発表され、深夜対応してました。
公式のパッチが出るまでの待ち時間で、なんとかできることを模索しつつ、ないなら作ればいいんじゃね?
ということで試行錯誤した内容を共有します。

2026 年 10 月 21 日(日本時間)に、PHP の重大な脆弱性 2 件(CVE-2026-109618・CVE-2026-109619、CVSS v4.0 9.2)の修正版が公開されました。認証なしでリモートコード実行ができるおそれがあります。

https://www.php.net/archive/2026.php#2026-10-21-1

8.2 系の修正版は 8.2.35 です。Amazon Linux 2023(以下 AL2023)の php8.2 は、2026 年 10 月 22 日 7 時の時点で、ALAS の CVE のページでは 2 件とも Pending Fix です。

今回は、AL2023 公式の php8.2 の SRPM を取り出し、ソースだけを 8.2.35 に差し替えて、AWS CodeBuild でビルドしました。手元の PC には負荷をかけずに済み、ビルドは約 7 分、動作確認は数分で終わりました。

調査・ビルド・動作確認は、生成 AI(Claude Code)に指示して進めました。

この記事では、その手順を紹介します。

方針

あくまで、公式パッケージを待ちつつ、動作確認などやれるものを先にやるために進めています。
公式パッケージがでたときに、変に邪魔しないよう考慮しています。

  • AL2023 公式の SRPM(今回は php8.2-8.2.34-1.amzn2023.0.1)を使う。設定ファイルの置き場所やパッケージの分け方が今と変わらない
  • 差し替えるのはソースの tarball だけにする。spec に入っているパッチ(Fedora の php.spec と同じ 10 種類)はそのまま当てる
  • リリース番号を 0.cm1 にする。今の 8.2.34-1 より新しく、公式の 8.2.35-1 より古いので、公式版が 8.2.35 で出たら自動更新で置き換わる
  • ビルドは CodeBuild で、素の AL2023 イメージ(public.ecr.aws/amazonlinux/amazonlinux:2023)を使う。標準イメージには別の PHP が入っていて、確認のときにそちらが動いてしまうため

生成AIとやってみた

生成AIに上記方針でやれ!って言いました。

1. CodeBuild の準備

成果物を置く S3 バケットと、CodeBuild 用の IAM ロールを作ります。ロールには、CloudWatch Logs への書き込みと、このバケットの読み書きだけを許可します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:ap-northeast-1:<アカウント ID>:log-group:/aws/codebuild/php-build*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:GetBucketLocation"],
      "Resource": ["arn:aws:s3:::<バケット名>", "arn:aws:s3:::<バケット名>/*"]
    }
  ]
}

プロジェクト名は php-build で、ソースなし(NO_SOURCE)で作り、buildspec をプロジェクトに直接書きました。

イメージは public.ecr.aws/amazonlinux/amazonlinux:2023、コンピューティングタイプは BUILD_GENERAL1_LARGE です。

2. buildspec

version: 0.2
env:
  shell: bash
  variables:
    # 元にする AL2023 公式の SRPM
    SRPM: php8.2-8.2.34-1.amzn2023.0.1
    # 差し替える PHP の版
    NEWVER: 8.2.35
    # php.net が公開している php-8.2.35.tar.xz の SHA256
    SHA256: 5737b98601fe5ab1b8c5db0c82ed3158acb9283ed3081ffe2faffb9ac81455e6
phases:
  install:
    commands:
      # ビルドに使うツールを入れる(gnupg2 は署名の検証用。gnupg2-minimal と入れ替えるため --allowerasing)
      - dnf install -y --allowerasing rpm-build dnf-plugins-core xz wget gnupg2
      # パッケージ名の末尾に付く dist タグ(.amzn2023)をログに出す
      - echo "dist=$(rpm --eval '%{?dist}')"
  pre_build:
    commands:
      # 公式の SRPM をダウンロードする
      - cd /tmp && dnf download --source "$SRPM"
      # SRPM を ~/rpmbuild に展開する(spec は SPECS、ソースとパッチは SOURCES)
      - rpm -ivh /tmp/${SRPM}.src.rpm
      # spec のパスをファイルに控え、後のコマンドで読み出す
      - SPEC=$(ls ~/rpmbuild/SPECS/*.spec | head -1); echo "$SPEC" > /tmp/specpath
      # 新しいソースを php.net から取り、SHA256 を照合する
      - cd ~/rpmbuild/SOURCES && wget -q https://www.php.net/distributions/php-${NEWVER}.tar.xz && echo "${SHA256}  php-${NEWVER}.tar.xz" | sha256sum -c -
      # 署名ファイルを取る(spec の %gpgverify が検証に使う)
      - cd ~/rpmbuild/SOURCES && wget -q https://www.php.net/distributions/php-${NEWVER}.tar.xz.asc
      # spec の版(%global upver)を 8.2.35 に、Release を 0.cm1 に書き換える
      - SPEC=$(cat /tmp/specpath); sed -i -E "s/^(%global[[:space:]]+upver[[:space:]]+)8\.2\.34/\1${NEWVER}/; s/^(Release:[[:space:]]*).*/\10.cm1%{?dist}/" "$SPEC"
      # spec が必要とするビルド用パッケージを入れる
      - SPEC=$(cat /tmp/specpath); dnf builddep -y "$SPEC"
      # ソースの展開とパッチ当てだけを行い、パッチが当たるかを先に確かめる
      - SPEC=$(cat /tmp/specpath); rpmbuild -bp "$SPEC" > /tmp/prep.log 2>&1 || { tail -80 /tmp/prep.log; exit 1; }
      # 署名の検証結果をログに出す
      - echo "PREP OK"; grep -i -E "gpgv|signature" /tmp/prep.log
  build:
    commands:
      # バイナリの RPM をビルドする(%check の make test は飛ばす)
      - SPEC=$(cat /tmp/specpath); rpmbuild -bb --nocheck "$SPEC" > /tmp/build.log 2>&1 || { tail -120 /tmp/build.log; exit 1; }
  post_build:
    commands:
      # 入れ替えたい 5 パッケージだけを集め、SHA256SUMS を作る
      - mkdir -p /tmp/out && cp ~/rpmbuild/RPMS/x86_64/php8.2-{cli,common,fpm,mbstring,xml}-${NEWVER}-*.rpm /tmp/out/ && cd /tmp/out && sha256sum *.rpm | tee SHA256SUMS
# /tmp/out の中身をすべて S3 に置く
artifacts:
  base-directory: /tmp/out
  files:
    - '*'

ポイントは次のとおりです。

  • SHA256 は php.net の JSON(https://www.php.net/releases/index.php?json&version=8.2)で公開されている値です。ビルドの中で照合します
  • spec の版は Version: ではなく %global upver で決まっていました。Version: %{upver}%{?rcver:~%{rcver}} という書き方です
  • spec の %gpgverify で署名を検証するので、.asc も SOURCES に置き、gnupg2 を入れます。素のイメージにある gnupg2-minimal とぶつかるため、--allowerasing を付けます
  • 本ビルドの前に rpmbuild -bp(ソースの展開とパッチ当てだけ)を挟みました。spec のパッチが新しいソースに当たらなければ、ここで早く止まります。今回はすべて当たりました
  • %check(make test)は --nocheck で飛ばしました。テストの結果は、次の「make test の結果」で別に確かめています
  • 取り出すのは、入れ替えたいパッケージ(cli・common・fpm・mbstring・xml)だけにしました

ビルドは約 7 分で終わりました。署名の検証は、ログに次のように出ます。

gpgv: Signature made Mon Oct 19 07:34:32 2026 UTC
gpgv:                using RSA key E60913E4DF209907D8E30D96659A97C9CF2A795A
gpgv: Good signature from "Sergey Panteleev <sergey@php.net>"

できた RPM は次の 5 つです。

php8.2-cli-8.2.35-0.cm1.amzn2023.x86_64.rpm
php8.2-common-8.2.35-0.cm1.amzn2023.x86_64.rpm
php8.2-fpm-8.2.35-0.cm1.amzn2023.x86_64.rpm
php8.2-mbstring-8.2.35-0.cm1.amzn2023.x86_64.rpm
php8.2-xml-8.2.35-0.cm1.amzn2023.x86_64.rpm

3. make test の結果

あとから、同じ buildspec で --nocheck を外して %check を流しました。テストは約 1 分で終わり、ビルド全体の時間は --nocheck のときとほぼ同じでした。

Number of tests : 18784             10854
Tests skipped   : 7930 ( 42.2%) --------
Tests failed    :    1 (  0.0%) (  0.0%)
Expected fail   :    6 (  0.0%) (  0.1%)
Tests passed    : 10847 ( 57.7%) ( 99.9%)

失敗した 1 件は ext/pcre/tests/gh11956.phpt(PCRE の JIT を使う正規表現のテスト)です。

差し替えをしない公式の 8.2.34 でも、同じテストが同じ結果で失敗しました。8.2.35 で増えた失敗はありません。

spec の %check は、テストが失敗してもビルドを止めません(exit 1 がコメントアウトされています)。テストを流すときは、ビルドの成否ではなくログの TEST RESULT SUMMARY を見てください。

4. 素の AL2023 で入れ替えを確認する

同じ CodeBuild プロジェクトで、別の buildspec を渡して確認しました(start-build の --buildspec-override)。8.2.34 と nginx を入れてから自作の RPM に入れ替え、nginx と php-fpm 経由のリクエストまで通します。素のイメージには AWS CLI がないので、RPM は aws s3 presign で作った署名付き URL から curl で取りました。

V=8.2.34-1.amzn2023.0.1
dnf install -y php8.2-cli-$V php8.2-common-$V php8.2-fpm-$V php8.2-mbstring-$V php8.2-xml-$V nginx
mkdir -p /tmp/rpms && cd /tmp/rpms
curl -sSf -o php8.2-fpm-8.2.35-0.cm1.amzn2023.x86_64.rpm '<署名付き URL>'   # 5 個と SHA256SUMS
sha256sum -c SHA256SUMS
md5sum /etc/php.ini /etc/php-fpm.d/www.conf > /tmp/conf-before.md5
dnf -y install /tmp/rpms/*.rpm
/usr/bin/php -v
md5sum -c /tmp/conf-before.md5
mkdir -p /run/php-fpm && /usr/sbin/php-fpm -D
echo '<?php echo "fpm ", PHP_VERSION, " ", php_sapi_name();' > /usr/share/nginx/html/v.php
echo '<?php echo count($_FILES), " ", $_FILES["f"]["size"] ?? 0;' > /usr/share/nginx/html/u.php
head -c 100000 /dev/urandom > /tmp/up.bin
/usr/sbin/nginx
curl -s http://127.0.0.1/v.php
curl -s -F f=@/tmp/up.bin http://127.0.0.1/u.php   # multipart の POST
dnf -y history undo last                           # 元に戻せるか

結果です。

== before
PHP 8.2.34 (cli) (built: Sep 22 2026 08:44:13) (NTS gcc x86_64)
== after
PHP 8.2.35 (cli) (built: Oct 19 2026 07:29:52) (NTS gcc x86_64)
== config unchanged
/etc/php.ini: OK
/etc/php-fpm.d/www.conf: OK
== http via nginx+fpm
fpm 8.2.35 fpm-fcgi [200]
== upload (multipart POST)
1 100000 [200]
== rollback
PHP 8.2.34 (cli) (built: Sep 22 2026 08:44:13) (NTS gcc x86_64)

5. サーバーへの入れ方

dnf upgrade は公式リポジトリしか見ないので、ファイルを指定して dnf install します。

sha256sum -c SHA256SUMS
sudo dnf -y install ./php8.2-*-8.2.35-0.cm1.amzn2023.x86_64.rpm
sudo systemctl restart php-fpm
php -v

rpm -q php8.2-fpm の結果に cm1 が付いていれば、自作ビルドの版です。戻すときは sudo dnf history undo last です。

自分の環境に合わせて変えるところ

PHPのバージョンや、OS など、自分の環境に合わせて変更してください。生成AIに指示を入れれば大体対応できるかと思います。

変えたいこと 変える場所
PHP のマイナー版(8.3・8.4 など) SRPM・NEWVER・SHA256 に加え、sed の 8\.2\.34 と post_build の php8.2- も合わせる。SRPM の版は dnf list --showduplicates php8.3、SHA256 は php.net の JSON(version=8.3)で調べる
取り出すパッケージ post_build の {cli,common,fpm,mbstring,xml}。サーバーで rpm -qa 'php8.2*' を見て、入っているものを並べる
リリース番号 cm1 は自分の識別子に変えてよい。先頭の 0. は残す

こちらで試したのは 8.2 系・x86_64 だけです。
そのあと、いくつか、バージョン違いで作成をしましたが、特に問題なさそうでした。

注意点

  • 公式の修正が 8.2.35 ではなく、8.2.34 に修正を取り込んだ版(例:8.2.34-2.amzn2023)で出た場合は、自作の 8.2.35-0.cm1 のほうが新しい扱いになり、自動では置き換わりません。dnf distro-sync 'php8.2*' で公式リポジトリの版に戻します
  • 確かめたのは PHP 本体のテストと簡単な動作確認だけです。本番の前にステージングでアプリの動作を確認することを強くお勧めします
  • php.net は「完全な回避策はなく、更新だけが安全」としています。

まとめ

AL2023 公式の SRPM を元に、ソースだけを差し替えて CodeBuild でビルドし、修正版の PHP を用意できました。
CodeBuild を用いることで手元の PC を使わずに済み、ビルドは約 7 分、動作確認は数分でした。

同じやり方は、今後似たような脆弱性や、ほかの RPM 系ディストリビューション、PHP 以外のパッケージにも使えると考えています。
その場合も、動作確認は本番と同じ素の OS イメージで行い、リリース番号は公式版より小さくして、公式パッケージの更新をなるべく邪魔せずに先行することができるかと思います。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事