Android 搭載端末では、Android のセキュリティ モデルが適用されます。その際に大きな役割を果たしているのがカーネルです。セキュリティ チームは、Android のユーザー空間の保護を強化し、プロセスを分離して特権を与えないようにするために作業を進めています。しかし、セキュリティ攻撃の対象としてカーネルが狙われることがますます多くなっています。カーネルを狙う攻撃者が一般的に用いる手法は、システムコールです。
あらゆる Android ソフトウェアは、システムコール(syscall と短縮されることもあります)を使って Linux カーネルと通信しています。カーネルは、多くの端末固有および SOC 固有のシステムコールを提供しています。それによって、アプリを含むユーザー空間プロセスが直接カーネルとやりとりを行えるようになっています。すべてのアプリは、このメカニズムを使って、一意なシステムコールによってインデックスがつけられた動作のコレクション(ファイルのオープンや Binder メッセージの送信など)にアクセスします。しかし Android では、こういったシステムコールの多くは利用されておらず、公式なサポートもされていません。
Android O は、利用されていないシステムコールをアプリのソフトウェアからアクセスできないようにする
seccomp と呼ばれる Linux 機能を活用します。アプリからこういったシステムコールにアクセスできなくなるため、有害である可能性があるアプリによって悪用されることもなくなります。
seccomp フィルタ
Android O には、zygote にインストールされた seccomp フィルタが 1 つ含まれています。zygote は、すべての Android アプリの派生元となるプロセスです。フィルタは zygote にインストールされているので、すべてのアプリにインストールされることになります。そのため、既存のアプリに問題が発生しないよう、Android セキュリティ チームは特別な注意を払いました。seccomp フィルタによって許可されるのは、以下のシステムコールです。
- bionic(Android 用の C ランタイム)経由で公開されているすべてのシステムコール。これは、bionic/libc/SYSCALLS.TXT で定義されています。
- Android を起動できるようにするシステムコール。
- 一般的な Android アプリに利用されるシステムコール。これは、Google の完全なアプリ互換性スイートを実行することで判断しています。
Android O の seccomp フィルタは、swapon/swapoff などの一部のシステムコールをブロックします。これらは、いくつかのセキュリティ攻撃や重要な制御用システムコールで使われることがありますが、アプリではあまり使われることはありません。このフィルタは合計で、arm64 では 271 のうち 17 のシステムコール、arm では 364 のうち 70 のシステムコールをブロックします。
デベロッパー
Android O を実行している端末でアプリをテストし、禁止されているシステムコールを使っていないかを確認してください。
禁止されているシステムコールの検出
Android O で禁止されているシステムコールを使おうとすると、システムがアプリをクラッシュさせます。ログには、禁止されているシステムコールが出力されます。次に例を示します。
03-09 16:39:32.122 15107 15107 I crash_dump32: performing dump of process 14942 (target tid = 14971)
03-09 16:39:32.127 15107 15107 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
03-09 16:39:32.127 15107 15107 F DEBUG : Build fingerprint: 'google/sailfish/sailfish:O/OPP1.170223.013/3795621:userdebug/dev-keys'
03-09 16:39:32.127 15107 15107 F DEBUG : Revision: '0'
03-09 16:39:32.127 15107 15107 F DEBUG : ABI: 'arm'
03-09 16:39:32.127 15107 15107 F DEBUG : pid: 14942, tid: 14971, name: WorkHandler >>> com.redacted <<<
03-09 16:39:32.127 15107 15107 F DEBUG : signal 31 (SIGSYS), code 1 (SYS_SECCOMP), fault addr --------
03-09 16:39:32.127 15107 15107 F DEBUG : Cause: seccomp prevented call to disallowed system call 55
03-09 16:39:32.127 15107 15107 F DEBUG : r0 00000091 r1 00000007 r2 ccd8c008 r3 00000001
03-09 16:39:32.127 15107 15107 F DEBUG : r4 00000000 r5 00000000 r6 00000000 r7 00000037
影響を受けるデベロッパーは、禁止されているシステムコールを呼ばないようにアプリを改修する必要があります。
テスト時の seccomp フィルタの切り替え
エラーのロギング以外にも利用できる機能があります。seccomp インストーラは、userdebug および eng ビルドが実行されている端末で setenforce に従います。これを使うと、問題を起こしているのが seccomp であるかどうかをテストができます。次のコマンドを実行すると、
adb shell setenforce 0 && adb stop && adb start
zygote に seccomp ポリシーはインストールされません。実行中のプロセスから seccomp ポリシーを削除することはできないため、このオプションを反映するにはシェルを再起動する必要があります。
端末メーカー
Android O には、
//bionic/libc/seccomp
に関連する seccomp フィルタが含まれています。そのため、端末メーカーが追加で実装する必要はありません。ただし、
//cts/tests/tests/security/jni/android_security_cts_SeccompTest.cpp
には、seccomp をチェックする CTS テストが配置されています。このテストは、
add_key
および
keyctl
システムコールがブロックされていること、また
openat
や、互換性のために必要となるいくつかのアプリ固有のシステムコールが許可されていることをチェックします。
Reviewed by