すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Linux:KFENCE を使用したカーネルメモリ汚染の検出

最終更新日:Sep 05, 2026

KFENCE (Kernel Electric-Fence) は、カーネルコードとモジュール内のメモリ破損を検出し、詳細なエラーレポートを生成する低オーバーヘッドの Linux カーネルツールです。

Alibaba Cloud Linux 3 は、動的な有効化/無効化、スラブ単位のモニタリング、メモリを考慮したプールサイズ設定によって KFENCE を強化し、本番環境とオフラインの両方での使用に対応します。

KFENCE の使用シナリオ

KFENCE は、CPU への影響を最小限に抑えるためにメモリを消費し、2 つの使用シナリオをサポートします。

  • 本番環境でのモニタリング:フリート全体でサンプリングモードを有効にします。十分なアップタイムがあれば、KFENCE はテストワークロードではほとんど実行されないコードパスのバグを検出します。パフォーマンスへの影響は無視でき、最大 2 MiB を消費します。

  • オフラインデバッグ:フルモードを有効にして、特定のスラブタイプのすべての割り当てをモニタリングします。GiB レベルのメモリを消費しますが、スコープ内のすべての割り当てを検出します。既知の問題を再現するのに最適です。

説明

カーネルおよびモジュールの開発者は、KFENCE を使用してコード内のメモリ破損を検出できます。クラッシュが発生したユーザーは、KFENCE を有効にして、Alibaba Cloud またはサードパーティのドライバー開発者向けにクラッシュデータを収集できます。

前提条件

KFENCE には、Alibaba Cloud Linux 3 の次の最小カーネルバージョンが必要です。

アーキテクチャ

最小カーネルバージョン

x86

5.10.84-10

Arm

5.10.134-16

KFENCE と Kernel Address Sanitizer (KASAN) の比較

どちらも、Linux カーネルに組み込まれているメモリ破損検出機能です。Alibaba Cloud は、カーネル 5.10 で KFENCE を強化しました。

比較項目

KFENCE

KASAN

監視範囲

最大 4 KiB のスラブ (例:kmalloc-4k) とオーダー 0 ページ

すべてのスラブタイプ、ページメモリ、スタックメモリ、グローバルメモリ

検出率

監視範囲内での成功率が高い

--

メモリオーバーヘッド

低い

高い

パフォーマンスへの影響

低い (本番環境に適しています)

高い (通常はテスト環境で使用されます)

説明

KFENCE と KASAN を同時に有効にしないでください。KFENCE は KASAN の監視オブジェクトを引き継ぎます。

基本概念

用語

説明

メモリ汚染

プログラムの実行中に意図しないメモリの変更や破損が発生し、例外やクラッシュを引き起こすこと。一般的な原因として、プログラミングエラー、ソフトウェアの脆弱性、マルウェア、ハードウェアの故障などがあります。

スラブ

頻繁なメモリオペレーションのオーバーヘッドを削減するために、キャッシュプールにオブジェクトを事前割り当てし、高速な割り当てと解放を実現するカーネルのメモリアロケーションメカニズム。

オーダー 0 ページ

Linux カーネルにおけるメモリアロケーションの最小単位である 4 KiB のページフレーム。

KFENCE の有効化

本番環境でのモニタリング

ライブ環境でメモリ破損を最小限のオーバーヘッドで検出します。

シナリオ 1:ブートパラメーターによるサンプリングモード

KFENCE は、一定の間隔でメモリアロケーションをサンプリングします。メモリ消費量は最大 2 MiB で、測定可能なパフォーマンスへの影響はありません。

  1. ブートパラメーター kfence.sample_interval を追加します。<sample-interval> をサンプリング間隔 (ミリ秒単位) に置き換えます。例: 100 = 100 ms ごと。

       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.sample_interval=<sample-interval>"
  2. (オプション) パラメーター kfence.booting_max を追加して、合計システムメモリに基づいて KFENCE のメモリを制限します。<booting-max> を 0-128M:0,128M-256M:1M,256M-:2M のようなセグメント表記文字列に置き換えます。

       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.booting_max=<booting-max>"
  3. 設定を有効にするには、インスタンスを再起動してください。

シナリオ 2:スクリプトによる特定スラブのフルモード

このモードでは、指定されたスラブタイプのすべての割り当てをモニタリングします。GiB レベルのメモリを消費するため、メモリが限られているマシンでは注意して使用してください。

  1. kfence.sh という名前のスクリプトを作成します。このスクリプトは、アクティブなスラブオブジェクトをカウントし、プールのサイズを決定し、他のスラブとオーダー 0 ページのモニタリングを無効にした後、指定されたスラブのフルモードモニタリングを有効にします。

    説明

    KFENCE はスラブとオーダー 0 ページの両方をモニタリングします。スラブは、頻繁に使用されるオブジェクトに対するカーネルの最適化された割り当てメカニズムです。

       #!/bin/bash
       # 使用方法:./kfence.sh kmalloc-64
    
       SLAB_PREFIX=/sys/kernel/slab
       MODULE_PREFIX=/sys/module/kfence/parameters
    
       if [ $# -eq 0 ]; then
       	echo "err: please input slabs"
       	exit 1
       fi
    
       # スラブが存在するかどうかを確認します
       for i in $@; do
       	slab_path=$SLAB_PREFIX/$i
       	if [ !  -d $slab_path ]; then
       		echo "err: slab $i not exist!"
       		exit 1
       	fi
       done
    
       # num_objects を計算します
       sumobj=0
       for i in $@; do
       	objects=($(cat $SLAB_PREFIX/$i/objects))
       	maxobj=1
       	for ((j=1; j<${#objects[@]}; j++)); do
       		nodeobj=$(echo ${objects[$j]} | awk -F= '{print $2}')
       		[ $maxobj -lt $nodeobj ] && maxobj=$nodeobj
       	done
       	((sumobj += maxobj))
       done
       echo "recommend num_objects per node: $sumobj"
    
       # kfence のステータスを確認します
       if [ $(cat $MODULE_PREFIX/sample_interval) -ne 0 ]; then
       	echo "kfence is running, disable it and wait..."
       	echo 0 > $MODULE_PREFIX/sample_interval
       	sleep 1
       fi
    
       # すべてのスラブのモニタリングを無効化します
       for file in $SLAB_PREFIX/*
       do
       	(echo 0 > $file/kfence_enable) 2>/dev/null || echo 1 > $file/skip_kfence
       done
    
       # order0 ページのモニタリングを無効化します
       echo 0 > $MODULE_PREFIX/order0_page
    
       # 設定したスラブのモニタリングを有効化します
       for i in $@; do
       	(echo 1 > $SLAB_PREFIX/$i/kfence_enable) 2>/dev/null || echo 0 > $SLAB_PREFIX/$i/skip_kfence
       done
    
       # num_objects とノードモードを設定します
       echo $sumobj > $MODULE_PREFIX/num_objects
       echo node > $MODULE_PREFIX/pool_mode
    
       # kfence を開始します
       echo -1 > $MODULE_PREFIX/sample_interval
       if [ $?  -ne 0 ]; then
       	echo "err: kfence enable fail!"
       	exit 1
       fi
       echo "kfence enabled!"
  2. 監視するスラブタイプを指定してスクリプトを実行します。

       sudo bash ./kfence.sh kmalloc-64

オフラインデバッグ

広範なスコープですべてのメモリアロケーションをキャプチャします。メモリ消費量は多くなりますが、検出カバレッジは最大になります。

ブートパラメーター (x86)

  1. 次のブートパラメーターを追加します。

    パラメーター

    この例での値

    効果

    num_objects

    1000000

    プールは最大 1,000,000 個のスラブオブジェクトをモニタリングでき、最大で ceil(1,000,000 / 131,071) = 8 GiB を消費します。利用可能なメモリの約 10% に設定します。

    sample_interval

    -1

    フルモード:設定されたスコープに一致するすべてのメモリをモニタリングします。

    fault

    panic

    問題が検出されるとカーネルパニックをトリガーし、分析用のコアダンプを保持します。

       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.num_objects=1000000"
       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.sample_interval=-1"
       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.fault=panic"
  2. 設定を有効にするには、インスタンスを再起動してください。

ランタイムパラメーター (x86 または Arm)

説明
  • ランタイムで有効化された KFENCE は、カーネル起動中のメモリ破損を検出できません。

  • KFENCE を有効にした後で num_objects または sample_interval を変更するには、まず KFENCE を無効にしてください。num_objects への変更は、次に KFENCE が有効になったときに反映されます。

次のコマンドを実行します。

sudo sh -c 'echo 1000000 > /sys/module/kfence/parameters/num_objects'
sudo sh -c 'echo -1 > /sys/module/kfence/parameters/sample_interval'
sudo sh -c 'echo panic > /sys/module/kfence/parameters/fault'

パラメーターは、上記の「ブートパラメーター (x86)」セクションで説明されている値と同じです。

説明

カーネルバージョンが 5.10.134-16 より前の場合、fault パラメーターは利用できません。このパラメーターに書き込もうとしたときのエラーメッセージは、無視しても問題ありません。

結果の確認

KFENCE を有効にした後、検出された問題を確認します。

検出統計の表示

sudo cat /sys/kernel/debug/kfence/stats

問題が検出された場合、total bugs のカウントは 0 より大きくなります。

エラー詳細の表示

dmesg | grep -i kfence

カーネルメッセージをフィルタリングして、KFENCE のエラーレポートを表示します。

KFENCE の無効化

KFENCE は、Alibaba Cloud Linux カーネルイメージに組み込まれた標準コンポーネントです (カーネル設定 CONFIG_KFENCE=y)。カーネルパッチ (kpatch)、ホットアップデート、またはソフトウェアパッケージでは無効にできません。無効にするには、次のコマンドを手動で実行します。

  1. KFENCE のモニタリングを停止します。KFENCE は新しい割り当てのモニタリングを停止します。プール内の監視対象メモリがすべて解放されると、KFENCE はそのメモリを 1 GiB 単位でカーネルのバディシステムに返します。

       sudo bash -c 'echo 0 > /sys/module/kfence/parameters/sample_interval'
  2. (オプション) KFENCE がブートパラメーターで有効化されていた場合は、そのパラメーターを削除して次回の起動時に KFENCE が開始されないようにします。

       sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --remove-args="kfence.sample_interval"

パラメーターリファレンス

KFENCE は、ブート引数またはランタイム時に /sys/module/kfence/parameters/ を介して設定します。

パラメーター

説明

有効な値

デフォルト

sample_interval

メモリモニタリングのサンプリング間隔

0 = 無効。正の整数 = ms 単位の間隔 (例:100 = 100 ms ごと)。負の整数 = フルモード (対象のすべてのメモリをモニタリング)。

--

num_objects

KFENCE プールがモニタリングできるスラブオブジェクトの最大数。プールのサイズとメモリ消費量を決定します。

正の整数。オフラインデバッグでは、利用可能な最大メモリの約 10% に設定します。

255

fault

メモリ破損が検出されたときのアクション。カーネル 5.10.134-16 以降で利用可能です。

report = エラーをログに記録します。panic = カーネルパニックをトリガーし、コアダンプを保持します。

report

booting_max

合計システムメモリに基づく KFENCE のメモリ制限。カーネル 5.10.134-17 以降で利用可能です。ブートコマンドライン設定にのみ適用されます。

セグメント表記。例: 0-2G:0,2G-32G:2M,32G-:32M

0-2G:0,2G-32G:2M,32G-:32M

order0_page

オーダー 0 ページのモニタリングの有効化または無効化

0 = 無効、1 = 有効

--

pool_mode

プール割り当て戦略

node = NUMA ノードごとのプール

--

メモリ消費量の計算式

最大メモリ消費量は num_objects に依存します。

  • num_objects が 131,071 以下の場合:(num_objects + 1) x 8 KiB

  • num_objects が 131,071 より大きい場合:ceil(num_objects / 131,071) GiB

例えば、num_objects を 1,000,000 に設定すると、最大消費量は ceil(1,000,000 / 131,071) = 8 GiB となります。

booting_max パラメーター

kfence.booting_max パラメーターは、合計システムメモリに基づいて KFENCE のメモリを制限します。各セグメントは、メモリ範囲を KFENCE の制限にマッピングします。

デフォルト設定 (カーネル 5.10.134-17 以降):

kfence.booting_max=0-2G:0,2G-32G:2M,32G-:32M

セグメント

意味

0-2G:0

合計メモリが 2 GiB 未満:KFENCE は無効

2G-32G:2M

合計メモリが 2 GiB から 32 GiB の間:KFENCE は最大 2 MiB を消費可能

32G-:32M

合計メモリが 32 GiB 超:KFENCE は最大 32 MiB を消費可能

デフォルトの num_objects である 255 を使用すると、KFENCE のメモリオーバーヘッドは合計メモリの 1 パーミル未満に留まります。標準の 4 KiB ページでは、最大消費量は 2 MiB です。64 KiB のヒュージページでは、32 MiB です。

説明

booting_max パラメーターは、起動時にのみ num_objects を制約します。実際のメモリ消費量は、この制限よりも少なくなる場合があります。このパラメーターは、KFENCE がランタイムで有効化された場合には適用されません。

カスタム例: 0-128M:0,128M-256M:1M,256M-:2M

セグメント

意味

0-128M:0

合計メモリが 128 MiB 未満:KFENCE は無効

128M-256M:1M

合計メモリが 128 MiB から 256 MiB の間:KFENCE は最大 1 MiB を消費可能 (num_objects の上限は 127)

256M-:2M

合計メモリが 256 MiB 超:KFENCE は最大 2 MiB を消費可能 (num_objects の上限は 255)

よくある質問

KFENCE のメモリとパフォーマンスへの影響はどの程度ですか?

モードによって異なります。

  • サンプリングモード (正の sample_interval を持つブートパラメーター):最大 2 MiB のメモリ消費。パフォーマンスへの影響は無視できます。本番環境での使用を推奨します。

  • 特定スラブのフルモード (ランタイムスクリプトまたは sample_interval=-1):GiB レベルのメモリ消費。モニタリングが特定のスラブタイプに限定されている場合、パフォーマンスへの影響は許容範囲内です。

  • 全スラブのフルモード (オフラインデバッグ):大幅なメモリ消費とパフォーマンスへの影響。専用のデバッグセッションでのみ使用してください。

本番環境にデプロイする前に段階的にテストを行い、ワークロードへの影響を測定してください。

既知の安定性の問題はありますか?

カーネル 5.10.134-15 以前では、特定のシナリオでオーダー 0 ページとスラブを同時にモニタリングすると、ダウンタイムが発生する可能性があります。これを防ぐには、オーダー 0 ページのモニタリングを無効にします。

sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.order0_page=0"

この問題は、カーネル 5.10.134-16 以降で解決されています。