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()
関数を使用するように変更する必要があります。