Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 1 | <html devsite><head> |
| 2 | <title>验证 SELinux</title> |
| 3 | <meta name="project_path" value="/_project.yaml"/> |
| 4 | <meta name="book_path" value="/_book.yaml"/> |
| 5 | </head> |
| 6 | <body> |
| 7 | <!-- |
| 8 | Copyright 2017 The Android Open Source Project |
| 9 | |
| 10 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 11 | you may not use this file except in compliance with the License. |
| 12 | You may obtain a copy of the License at |
| 13 | |
| 14 | http://www.apache.org/licenses/LICENSE-2.0 |
| 15 | |
| 16 | Unless required by applicable law or agreed to in writing, software |
| 17 | distributed under the License is distributed on an "AS IS" BASIS, |
| 18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 19 | See the License for the specific language governing permissions and |
| 20 | limitations under the License. |
| 21 | --> |
| 22 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 23 | <p>Android 强烈建议 OEM 全面测试其 SELinux 实现。制造商在实现 SELinux 时,应先在一组测试设备上实施新政策。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 24 | |
Android Partner Docs | 04c1f72 | 2018-08-21 09:08:03 -0700 | [diff] [blame] | 25 | <p>实施新政策后,您可以通过执行 <code>getenforce</code> 命令来确认 SELinux 在设备上的运行模式是否正确。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 26 | |
Android Partner Docs | 04c1f72 | 2018-08-21 09:08:03 -0700 | [diff] [blame] | 27 | <p>该命令会显示全局 SELinux 模式:强制或宽容。要确定每个域的 SELinux 模式,您必须查看相应的文件,或运行带有适当 (<code>-p</code>) 标记的最新版 <code>sepolicy-analyze</code>(位于 <a href="https://android.googlesource.com/platform/system/sepolicy/+/master/tools/" class="external"><code>/platform/system/sepolicy/tools/</code></a> 中)。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 28 | |
| 29 | <h2 id="reading_denials">读取拒绝事件</h2> |
| 30 | |
Android Partner Docs | 04c1f72 | 2018-08-21 09:08:03 -0700 | [diff] [blame] | 31 | <p>检查是否有错误,错误会以事件日志的形式传给 <code>dmesg</code> 和 <code>logcat</code>,并可在设备上从本地查看。制造商应先检查这些设备上传给 <code>dmesg</code> 的 SELinux 输出并优化设置,然后再在宽容模式下公开发布,最后切换到强制模式。SELinux 日志消息中包含“<code>avc:</code>”字样,因此可使用 <code>grep</code> 轻松找到。您可以通过运行 <code>cat /proc/kmsg</code> 来获取当前的拒绝事件日志,也可以通过运行 <code>cat /sys/fs/pstore/console-ramoops</code> 来获取上次启动时的拒绝事件日志。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 32 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 33 | <p>根据这些输出内容,制造商可以轻松发现系统用户或组件违反 SELinux 政策的行为。然后,制造商便可更改相应软件和/或 SELinux 政策,以防范此类恶意行为。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 34 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 35 | <p>具体来说,这些日志消息会指明在强制模式下哪些进程会失败以及失败原因。示例如下:</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 36 | |
| 37 | <pre> |
| 38 | avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" |
| 39 | scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket |
| 40 | </pre> |
| 41 | |
| 42 | <p>该输出的解读如下:</p> |
| 43 | |
| 44 | <ul> |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 45 | <li>上方的 <code>{ connectto }</code> 表示执行的操作。根据它和末尾的 <code>tclass</code> (<code>unix_stream_socket</code>),您可以大致了解是对什么对象执行什么操作。在此例中,是操作方正在试图连接到 UNIX 信息流套接字。 |
| 46 | </li><li><code>scontext (u:r:shell:s0)</code> 表示发起相应操作的环境,在此例中是 shell 中运行的某个程序。 |
| 47 | </li><li><code>tcontext (u:r:netd:s0)</code> 表示操作目标的环境,在此例中是归 <code>netd</code> 所有的某个 unix_stream_socket。 |
| 48 | </li><li>顶部的 <code>comm="ping"</code> 可帮助您了解拒绝事件发生时正在运行的程序。在此示例中,给出的信息非常清晰明了。 |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 49 | </li></ul> |
| 50 | |
Android Partner Docs | 04c1f72 | 2018-08-21 09:08:03 -0700 | [diff] [blame] | 51 | <p>我们再看看另一个示例:</p> |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 52 | <pre class="devsite-terminal devsite-click-to-copy">adb shell su root dmesg | grep 'avc: '</pre> |
| 53 | <p>输出:</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 54 | <pre> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 55 | <5> type=1400 audit: avc: denied { read write } for pid=177 |
| 56 | comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 |
| 57 | tcontext=u:object_r:kmem_device:s0 tclass=chr_file |
| 58 | </pre> |
| 59 | |
| 60 | <p>以下是此拒绝事件的关键元素:</p> |
| 61 | |
| 62 | <ul> |
Android Partner Docs | 179abc8 | 2018-11-26 10:32:17 -0800 | [diff] [blame^] | 63 | <li>操作 - 试图进行的操作会使用括号突出显示:<code>read write</code> 或 <code>setenforce</code>。<em></em> |
| 64 | </li><li>操作方 - <code>scontext</code>(来源环境)条目表示操作方;在此例中为<code> rmt_storage</code> 守护进程。<em></em> |
| 65 | </li><li>对象 - <code>tcontext</code>(目标环境)条目表示是对哪个对象执行操作;在此例中为 kmem。<em></em> |
| 66 | </li><li>结果 - <code>tclass</code>(目标类别)条目表示操作对象的类型;在此例中为 <code>chr_file</code>(字符设备)。<em></em> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 67 | </li></ul> |
| 68 | |
| 69 | <h2 id="switching_to_permissive">切换到宽容模式</h2> |
| 70 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 71 | <p class="caution"><strong>重要提示</strong>:生产设备不支持宽容模式。CTS 测试会确认是否已启用强制模式。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 72 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 73 | <p>SELinux 强制模式可以在 userdebug 或 eng 版本中通过 ADB 停用。为此,请先运行 <code>adb root</code> 以将 ADB 切换为 root 权限。然后,要停用 SELinux 强制模式,请运行以下命令: |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 74 | </p><pre class="devsite-terminal devsite-click-to-copy"> |
| 75 | adb shell setenforce 0 |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 76 | </pre> |
| 77 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 78 | <p>或在内核命令行中输入以下命令(适用于设备开发初期):</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 79 | |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 80 | <pre class="devsite-click-to-copy"> |
| 81 | <code class="devsite-terminal">androidboot.selinux=permissive</code> |
| 82 | <code class="devsite-terminal">androidboot.selinux=enforcing</code> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 83 | </pre> |
| 84 | |
| 85 | <h2 id="using_audit2allow">使用 audit2allow</h2> |
| 86 | |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 87 | <p><code>selinux/policycoreutils/audit2allow</code> 工具可以获取 <code>dmesg</code> 拒绝事件并将其转换成相应的 SELinux 政策声明。因此,该工具有助于大幅加快 SELinux 开发速度。 |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 88 | <code>audit2allow</code> 包含在 Android 源代码树中,会在您基于源代码编译 Android 时自动编译。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 89 | |
| 90 | <p>要使用该工具,请运行以下命令:</p> |
| 91 | |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 92 | <pre class="devsite-click-to-copy"> |
| 93 | <code class="devsite-terminal">adb pull /sys/fs/selinux/policy</code> |
| 94 | <code class="devsite-terminal">adb logcat -b all -d | audit2allow -p policy</code> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 95 | </pre> |
| 96 | |
Android Partner Docs | e0c4fe2 | 2018-07-24 13:05:33 -0700 | [diff] [blame] | 97 | <p class="note"><strong>注意</strong>:运行这些命令不会更改 bugreport.txt,因为所有日志都已经存在,包括上次重新启动之前存在的日志。在设备进行 OTA 更新或向设备刷入开发版系统时,新旧违规行为会混杂在一起,直到下一次重新启动为止。要解决此问题,请重新启动设备,或者从您的错误报告中滤除 console-ramoops 和 LAST_LOGCAT。 |
Android Partner Docs | ac7267d | 2017-11-27 14:00:50 -0800 | [diff] [blame] | 98 | </p> |
| 99 | |
Android Partner Docs | acec43a | 2018-02-20 17:03:25 -0800 | [diff] [blame] | 100 | <p>不过,请务必仔细审核要添加到政策中的条目,以免出现权限过宽的情况。例如,如果将上面的 <code>rmt_storage</code> 拒绝事件输入到 audit2allow 中,会生成以下 SELinux 政策声明建议:</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 101 | |
| 102 | <pre> |
| 103 | #============= shell ============== |
| 104 | allow shell kernel:security setenforce; |
| 105 | #============= rmt ============== |
| 106 | allow rmt kmem_device:chr_file { read write }; |
| 107 | </pre> |
| 108 | |
Android Partner Docs | 179abc8 | 2018-11-26 10:32:17 -0800 | [diff] [blame^] | 109 | <p>这会授予 <code>rmt</code> 向内核内存写入内容的权限,从而形成明显的安全漏洞。通常情况下,<code>audit2allow</code> 给出的声明建议只是一个大致的基础。在添加这些声明后,您可能需要更改来源域和目标标签,并纳入适当的宏,才能实现良好的政策配置。有时,应对拒绝事件的合理方式不是更改政策,而是更改违规的应用。</p> |
Ruslan Piasetskyi | 7b7ac1c | 2017-07-11 09:49:32 -0700 | [diff] [blame] | 110 | |
| 111 | </body></html> |