
CVE-2026-31431の分析と緩和ガイド。Linuxカーネルのcrypto algif_aeadサブシステムにおけるローカル権限昇格の脆弱性であり、RHELおよびOpenShiftへの影響評価、seccompおよびSCCの強化を含む。
Linuxカーネルのcrypto algif_aead サブシステムにおけるローカル権限昇格。
CVE-2026-31431、通称「Copy Fail」は、Linuxカーネルの authencesn 暗号テンプレート(algif_aead)における論理バグです。これにより、権限のないローカルユーザーが任意の読み取り可能なファイルのページキャッシュに対して制御された4バイト書き込みを行うことができ、setuidバイナリを改変してrootを取得するために悪用される可能性があります。
a664bf3d603d| 日付 | イベント |
|---|---|
| 2026-03-23 | Linuxカーネルセキュリティチームに報告 |
| 2026-04-01 | メインラインにパッチがコミット |
| 2026-04-22 | CVE採番 |
| 2026-04-29 | 公開開示 |
このエクスプロイトには、AF_ALG ソケット(すべてのseccompプロファイルでデフォルトで許可)とsetuidバイナリ(例: /usr/bin/su)の2つが必要です。主要な緩和策は allowPrivilegeEscalation: false です。これは、Linuxカーネルの no_new_privs フラグを prctl(PR_SET_NO_NEW_PRIVS, 1) で設定し、カーネルが execve() 時にsetuid/setgidビットを無視するようにします。エクスプロイトは改変されたsetuidバイナリの実行に依存するため、これにより最終的な権限昇格ステップがブロックされます。
これはOpenShift固有の機能ではありません — 通常のKubernetes(Pod Security Standards Restricted)、Docker(--security-opt no-new-privileges)、Podmanでも同様に機能します。OpenShiftは単に restricted-v2 SCCを介してデフォルトでこれを強制しますが、他のプラットフォームでは明示的な設定が必要です。
RHEL 8およびRHEL 9には、脆弱なコードを含むカーネルが同梱されています。シェルアクセスを持つ権限のないローカルユーザーは、これを悪用してrootを取得できます。直ちにパッチを適用してください。
yum updateinfo list cves CVE-2026-31431
yum update kernel
OpenShiftはRHCOS上で動作し、脆弱なカーネルが同梱されています。実際の影響は、ワークロードのSecurity Context Constraints(SCC)に依存します。
デフォルトの restricted-v2 SCCを使用する標準ワークロードは、allowPrivilegeEscalation: false が強制されるため、悪用できません。
昇格されたSCC(anyuid、privileged、または allowPrivilegeEscalation: true を許可するカスタムSCC)で実行されるPodは脆弱です。これには一般的に以下が含まれます:
anyuid を必要とするレガシーアプリケーションノードへの直接アクセス(例: oc debug node/ 経由)は常に脆弱です — 標準的なローカル権限昇格であり、コンテナ分離は関与しません。
クラスター内でエクスプロイトの前提条件が満たされているかどうかを確認するためのテストPodが提供されています。これは脆弱性の悪用を試みません — 以下のみをチェックします:
AF_ALG ソケットを作成できるか?(カーネル攻撃面に到達可能)no_new_privs が設定されているか?(setuid昇格をブロック)oc apply -f test-pod.yaml
oc logs cve-2026-31431-check
oc delete -f test-pod.yaml
Deploymentバリアントを使用して、レプリカをスケーリングするかPodアンチアフィニティを使用して複数のノードでテストします:
oc apply -f test-deployment.yaml
oc logs -l app=cve-2026-31431-check
oc delete -f test-deployment.yaml
| コード | 意味 |
|---|---|
0 | 悪用不可 — AF_ALGソケットがseccompによってブロックされている |
1 | 部分的に露出 — AF_ALGに到達可能だが、setuidが no_new_privs によってブロックされている |
2 | 脆弱 — すべてのエクスプロイト前提条件が満たされている |
標準的なOpenShiftクラスターで restricted-v2 SCCを使用している場合、終了コード 1(部分的に露出)が表示されるはずです: AF_ALGソケットは作成できますが(RuntimeDefault seccompはこれをブロックしません)、no_new_privs がsetuid昇格ステップを防ぎます。公開されたPoCは機能しませんが、カーネルレベルの脆弱性には依然として到達可能です — パッチ適用が推奨されます。
これが唯一の完全な修正です。すべてのノードのカーネルを更新し、再起動します。
OpenShiftの場合、修正を含むRHCOSバージョンに更新し、ローリングノード再起動を実行します。
algif_aead がロード可能なモジュール(CONFIG_CRYPTO_USER_API_AEAD=m)としてコンパイルされている場合:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
これは algif_aead が組み込み(=y)の場合には機能しません。これはRHCOSの場合に該当します。以下で確認してください:
modinfo algif_aead 2>&1 | grep builtin
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
カーネルモジュールが組み込みの場合、パッチ適用前のコンテナ向けの唯一の緩和策は、カスタムseccompプロファイルを介して socket(AF_ALG, ...) システムコールをブロックすることです。
MachineConfigを作成して、すべてのノードにプロファイルを配置します(コントロールプレーンノードには role: master で繰り返します):
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 99-worker-seccomp-deny-af-alg
spec:
config:
ignition:
version: 3.2.0
storage:
files:
- path: /var/lib/kubelet/seccomp/deny-af-alg.json
mode: 0644
contents:
source: data:application/json;charset=utf-8;base64,ewogICJkZWZhdWx0QWN0aW9uIjogIlNDTVBfQUNUX0FMTE9XIiwKICAic3lzY2FsbHMiOiBbCiAgICB7CiAgICAgICJuYW1lcyI6IFsic29ja2V0Il0sCiAgICAgICJhY3Rpb24iOiAiU0NNUF9BQ1RfRVJSTk8iLAogICAgICAiYXJncyI6IFsKICAgICAgICB7CiAgICAgICAgICAiaW5kZXgiOiAwLAogICAgICAgICAgInZhbHVlIjogMzgsCiAgICAgICAgICAib3AiOiAiU0NNUF9DTVBfRVEiCiAgICAgICAgfQogICAgICBdCiAgICB9CiAgXQp9
base64コンテンツは以下にデコードされます:
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ"
}
]
}
]
}
注: MachineConfigを適用すると、ローリングノード再起動がトリガーされます。
securityContext:
seccompProfile:
type: Localhost
localhostProfile: deny-af-alg.json
Pod仕様を変更せずにすべてのコンテナを保護するには、既存のプロファイルにAF_ALGフィルタールールを追加して、MachineConfigを介してCRI-Oのデフォルトseccompプロファイル(/etc/crio/seccomp.json)を上書きします。
昇格された権限で実行されているPodを特定します:
# restricted-v2を使用していないPodを検索
oc get pods -A -o json | jq -r '
.items[] |
select(.metadata.annotations["openshift.io/scc"] != "restricted-v2") |
"\(.metadata.namespace)/\(.metadata.name) → \(.metadata.annotations["openshift.io/scc"])"
'
これらは、完全なエクスプロイトチェーンが機能するPodです。これらのワークロードを実行しているノードのパッチ適用またはseccomp緩和策を優先してください。
AF_ALGソケットのブロックは、ほとんどのワークロードに無視できる影響しか与えません。以下は影響を受けません:
OpenSSL afalg エンジンを使用するように明示的に設定されたアプリケーションのみが影響を受けます。
| 環境 | allowPrivilegeEscalation | コンテナroot | ホストroot | リスク |
|---|
| RHEL 8 / RHEL 9(ローカルユーザー) | n/a | n/a | あり | 重大 |
OpenShiftノード(シェルアクセス、例: oc debug node/) | n/a | n/a | あり | 重大 |
OpenShift Pod — restricted-v2 SCC(デフォルト) | false | なし | なし | 低 |
OpenShift Pod — anyuid SCC | true | あり | なし(名前空間分離) | 高 |
OpenShift Pod — privileged SCC | true | あり | あり(分離なし) | 重大 |
| OpenShift Pod — カスタムSCC | 依存 | 依存 | 依存 | 監査 |
| Kubernetes Pod — PSS Restricted | false | なし | なし | 低 |
| Kubernetes Pod — PSS Baseline / ポリシーなし | true(デフォルト) | あり | なし | 高 |
Docker / Podman — --security-opt no-new-privileges | false | なし | なし | 低 |
| Docker / Podman — デフォルト | true | あり | なし | 高 |