カーネルの強化

Android 8.0 では、カーネルの脆弱性を緩和し、カーネル ドライバのバグを検出するためのカーネル強化機能が追加されました。これらの機能は、android-3.18、android-4.4、android-4.9 ブランチの kernel/common にあります。

実装

これらの機能を利用するには、デバイス メーカーと SOC が、kernel/common にあるすべての強化パッチをカーネルツリーに統合し、次のカーネル構成オプションを有効にする必要があります。

  • 強化された usercopy: CONFIG_HARDENED_USERCOPY=y
  • PAN エミュレーション - arm64: CONFIG_ARM64_SW_TTBR0_PAN=y
  • PAN エミュレーション - arm: CONFIG_CPU_SW_DOMAIN_PAN=y
  • KASLR - 4.4 以降のカーネル: CONFIG_RANDOMIZE_BASE=y

KASLR には、デバイスツリー ノードの /chosen/kaslr-seed を使用して、または EFI_RNG_PROTOCOL を実装することによってハードウェアのエントロピーを渡すために、ブートローダーのサポートも必要です。

既存の強化機能が有効になっていることも確認します。

  • スタック バッファ オーバーフローの緩和: CONFIG_CC_STACKPROTECTOR_STRONG=y
  • 内部メモリの保護: CONFIG_DEBUG_RODATA=y または CONFIG_STRICT_KERNEL_RWX=y
  • カーネルからユーザー空間へのアクセスの制限 - x86(デフォルトで有効): CONFIG_X86_SMAP=y

テスト

実装をテストするには、CONFIG_LKDTM=y をカーネル構成に追加し、次の各コマンドがカーネル パニックを引き起こすことを確認します。

echo ACCESS_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT
echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT
echo WRITE_RO > /sys/kernel/debug/provoke-crash/DIRECT
echo WRITE_RO_AFTER_INIT > /sys/kernel/debug/provoke-crash/DIRECT
echo WRITE_KERN > /sys/kernel/debug/provoke-crash/DIRECT
echo EXEC_STACK > /sys/kernel/debug/provoke-crash/DIRECT
echo EXEC_RODATA > /sys/kernel/debug/provoke-crash/DIRECT
echo EXEC_KMALLOC > /sys/kernel/debug/provoke-crash/DIRECT
echo EXEC_VMALLOC > /sys/kernel/debug/provoke-crash/DIRECT
echo CORRUPT_STACK > /sys/kernel/debug/provoke-crash/DIRECT

android-4.9 の場合:

echo USERCOPY_HEAP_SIZE_TO > /sys/kernel/debug/provoke-crash/DIRECT
echo USERCOPY_HEAP_SIZE_FROM > /sys/kernel/debug/provoke-crash/DIRECT

よくある問題

これらの変更により、カーネル ドライバのバグが明らかになる可能性があります。その場合はデバイス メーカーまたはカーネル ドライバの所有者が修正する必要があります。

  • 強化された usercopy により、ユーザー空間との間でデータをコピーするときに不正な境界チェックが明らかになります。これらの問題は、他のメモリ破損のバグと同様に修正する必要があります。
  • PAN エミュレーションにより、カーネルからユーザー空間への直接アクセスが公開されますが、これは許可されていません。ユーザー空間のメモリにアクセスしようとしているドライバは、代わりに標準的な copy_to_user() または copy_from_user() 関数を使用するように変更する必要があります。