Chrome for Android的sandbox机制
与其他大部分浏览其不同的是,Chrome采用的是多进程框架(http://www.chromium.org/developers/design-documents/multi-process-architecture),多进程框架除了稳定、快速之外一个非常重要的特点是可以方便的提供Sandbox机制来隔离网页渲染以及不安全脚本,使得浏览器更加安全。关于Linux下面的Chrome的Sandbox机制前面的文章已经经过相应的分析,本篇主要分析Chrome for Android中的Sandbox机制的实现。
Chrome for Android相对于Android Browser(WebKit-based)的重要的一个优点是利用了Android系统机制来提供Sandbox的支持。Android Browser是单进程的,即界面与网页渲染、脚本引擎都在同一个进程中,理论上不安全的脚本可能直接访问到Android Browser的数据,或是其他渲染页面的隐私数据。 而Chrome for Android则通过Sandbox对这些行为进行了有效的隔离。
打开Chrome并浏览网页,我们可以通过adb看到不止一个Chrome进程:
$ adb shell ps |grep chrome u0_a14 30488 133 640160 108380 ffffffff 40073823 S com.android.chrome u0_i183 30507 133 586036 51800 ffffffff 40073823 S com.android.chrome:sandboxed_process0 u0_i185 30607 133 589576 54368 ffffffff 40073823 S com.android.chrome:sandboxed_process2
其中com.android.chrome即Chrome的Browser进程(负责浏览器界面、事件处理、GPU线程、标签管理、书签及历史记录管理),而com.android.chrome:sandboxed_processX则为renderer进程,由于Chrome并未完全开源,我们通过Content Shell分析更为直接:
$adb shell ps |grep content u0_a82 30654 133 802692 95876 ffffffff 40073823 S org.chromium.content_shell u0_i186 30683 133 742732 54528 ffffffff 40073823 S org.chromium.content_shell:sandboxed_process0
org.chromium.content_shell是Browser进程,而org.chromium.content_shell:sandboxed_processX是Renderer进程。org.chromium.content_shell是Content Shell的主界面进程,而org.chromium.content_shell:sandboxed_processX是Browser进程通过BindService创建出来的Service, 在ContentShell的AndroidManifest.xml文件中描述了这些Sandboxed Service:
<service android:name="org.chromium.content.app.SandboxedProcessService0" android:process=":sandboxed_process0" android:permission="org.chromium.content_shell.permission.SANDBOX" android:isolatedProcess="true" android:exported="false" /> <service android:name="org.chromium.content.app.SandboxedProcessService1" android:process=":sandboxed_process1" android:permission="org.chromium.content_shell.permission.SANDBOX" android:isolatedProcess="true" android:exported="false" />
那么这些Sandboxed Service又是怎么做到与Browser进程隔离的呢?这依赖于Android所提供的Process UID Isolation,每一个不同的进程都对应一个唯一的UID(上面的ContentShell的例子中,Browser进程的UID是u0_a82,而Renderer进程是u0_i186 ), 隶属于不同UID之间的进程相互之间隔离,从而实现了Sandbox。具体Android Application Sandbox参见http://source.android.com/tech/security/#the-application-sandbox