1# OpenHarmony SELinux Check问题处理指导 2 3## 概述 4 5为规范OpenHarmony SELinux策略配置,针对neverallow检查无法覆盖到的场景和人工审核容易遗漏的问题,OpenHarmony提供了一套SELinux策略检查工具。 6 7 8## file_contexts中data分区二级目录使用正则表达式检查 9 10### 检查说明 11 12data分区为可读写分区,大部分进程的数据文件和用户的文件存放在data分区,文件数量庞大,容易出现碎片化问题。为避免data分区打标签性能问题,需要限制data分区的二级目录不能存在正则表达式,该检查主要扫描`file_contexts`文件。 13 14### 编译拦截 15 16在`file_contexts`中,data分区二级目录使用正则表达式,会触发编译报错,关键报错信息`Regex is not allowed in the secondary directory under data`,报错如下: 17```text 18Regex is not allowed in the secondary directory under data, check '/data/log(/.*)?' failed in file out/rk3568/obj/base/security/selinux_adapter/file_contexts:214 19 There are two solutions: 20 1. Add '/data/log(/.*)?' to whitelist file 'data_regex_whitelist.txt' under 'base/security/selinux_adapter/sepolicy'; 21 2. Modify '/data/log(/.*)?' to remove the regular expression 22``` 23 24### 拦截原因 25 26说明以下`file_contexts`中的定义是非法的,因为`log(/.*)?`是正则表达式,且在data的第二级目录: 27```text 28/data/log(/.*)? u:object_r:data_log:s0 29``` 30 31### 修复方法 32 33主要有两种修复方式: 34 35- 方式一:将不满足的路径`/data/log/(.*)?`添加到`//base/security/selinux_adapter/sepolicy/`下的白名单文件`data_regex_whitelist.txt`中,修改该白名单需要评估安全性和合理性,审慎修改。 36- 方式二:修改data二级目录中不合理的正则表达式,以满足要求,例如,改成以下形式,则是合法的: 37 ```text 38 /data/log u:object_r:data_log:s0 39 /data/log/(.*)? u:object_r:data_log:s0 40 ``` 41 42## file_contexts中使用一级目录标签检查 43 44### 检查说明 45 46一级目录标签是指根路径下的子目录使用的标签,主要有: 47```text 48u:object_r:dev_file:s0 49u:object_r:etc_file:s0 50u:object_r:lib_file:s0 51u:object_r:config_file:s0 52u:object_r:updater_file:s0 53u:object_r:system_file:s0 54u:object_r:sys_prod_file:s0 55u:object_r:chip_prod_file:s0 56u:object_r:vendor_file:s0 57u:object_r:data_file:s0 58u:object_r:module_update_file:s0 59``` 60 61`file_contexts`中禁止使用一级目录标签来定义路径标签,避免配置不合理的SELinux权限,对根路径的子目录产生影响,构成安全隐患。 62 63### 编译拦截 64 65在`file_contexts`配置中,不合理的使用一级目录标签,会触发编译报错,关键报错信息`partition label is not allow to use`,报错如下: 66 67``` 68partition label is not allow to use, check '/data/log u:object_r:data_file:s0' failed in file out/rk3568/obj/base/security/selinux_adapter/file_contexts:213 69 There are two solutions: 70 1. Add '/data/log u:object_r:data_file:s0' to whitelist file 'partition_label_use_whitelist.txt' under 'base/security/selinux_adapter/sepolicy'; 71 2. Change '/data/log u:object_r:data_file:s0' to avoid using label in ['u:object_r:dev_file:s0', 'u:object_r:etc_file:s0', 'u:object_r:lib_file:s0', 'u:object_r:config_file:s0', 'u:object_r:updater_file:s0', 'u:object_r:system_file:s0', 'u:object_r:sys_prod_file:s0', 'u:object_r:chip_prod_file:s0', 'u:object_r:vendor_file:s0', 'u:object_r:data_file:s0', 'u:object_r:module_update_file:s0'] 72``` 73 74### 拦截原因 75 76说明以下`file_contexts`中的定义是非法的,因为为`/data/log`配置了标签`u:object_r:data_file:s0`,该标签属于一级目录标签: 77```text 78/data/log u:object_r:data_file:s0 79``` 80 81### 修复方法 82 83主要有两种修复方式: 84 85- 方式一:将不满足的路径及标签`'/data/log u:object_r:data_file:s0'`添加到`//base/security/selinux_adapter/sepolicy/`下的白名单文件`partition_label_use_whitelist.txt`中,修改该白名单需要评估安全性和合理性,审慎修改。 86- 方式二:更改`/data/log`的不合理标签,使用自定义标签,以满足要求,例如,改成以下形式,则是合法的: 87 ```text 88 /data/log u:object_r:data_log:s0 89 ``` 90 91## 使用高危组合权限检查 92 93### 检查说明 94 95当某一对主体和客体同时拥有几个不同的SELinux权限时,可能形成一种攻击路径。此检查项主要检查user版本策略和开发者模式策略。检查项的配置文件在`base/security/selinux_adapter/scripts/selinux_check/config/perm_group.json`,形式如下: 96```json 97{ 98 "check_rules": [ 99 { 100 "name": "execute and execute_no_trans", 101 "description": "process label should transform while execute a file", 102 "perm_group": [ 103 { 104 "tclass": "*", 105 "perm": "execute execute_no_trans" 106 } 107 ] 108 } 109 ] 110} 111``` 112 113其中,`check_rules`表示所有权限组合检查项列表,每一个检查项中包括`name`、`description`、`perm_group`三个字段,`name`表示检查项的名称,`description`表示检查项描述,`perm_group`表示详细的可能存在攻击路径的权限列表,其中`tclass`表示操作类型,`perm`表示该操作类型下的权限,`tclass`可以填具体操作类型,也可以填`*`,填`*`表示会检查所有包括`perm`中权限的操作类型。 114 115### 编译拦截 116 117不合理的权限配置,会触发编译报错,关键报错信息`check rule 'xxx' in user mode failed`,这里的`xxx`表示被拦截的检查项`name`,报错如下: 118```text 119 check rule 'execute and execute_no_trans' in user mode failed, process label should transform while execute a file 120 violation list (scontext tcontext): 121 appspawn appspawn_exec 122 There are two solutions: 123 1. Add the above list to whitelist file 'perm_group_whitelist.json' under 'base/security/selinux_adapter/sepolicy' in 'user' part of 'execute and execute_no_trans' 124 2. Change the policy to avoid violating rule 'execute and execute_no_trans' 125 126 check rule 'execute and execute_no_trans' in developer mode failed, process label should transform while execute a file 127 violation list (scontext tcontext): 128 appspawn appspawn_exec 129 There are two solutions: 130 3. Add the above list to whitelist file 'perm_group_whitelist.json' under 'base/security/selinux_adapter/sepolicy' in 'developer' part of 'execute and execute_no_trans' 131 4. Change the policy to avoid violating rule 'execute and execute_no_trans' 132``` 133 134### 拦截原因 135 136上述报错是因为,在user策略和开发者策略中,主体`appspawn`和客体`appspawn_exec`,都同时拥有`execute`和`execute_no_trans`权限: 137```text 138allow appspawn appspawn_exec:file { execute execute_no_trans }; 139``` 140 141### 修复方法 142 143主要有两种修复方式: 144 145- 方式一:将不合理的主体和客体组合添加到`//base/security/selinux_adapter/sepolicy/`下的白名单文件`perm_group_whitelist.json`中,修改该白名单需要评估合理性,审慎添加,该文件如下: 146 ```text 147 { 148 "whitelist": [ 149 { 150 "name": "execute and execute_no_trans", 151 "user": [ 152 "appspawn appspawn_exec" 153 ], 154 "developer": [ 155 ] 156 } 157 ] 158 } 159 ``` 160 其中,`whitelist`表示所有权限组合检查项白名单列表,每一个检查项白名单中包括`name`、`user`、`developer`三个字段,`name`表示检查项白名单的名称,与检查项`name`对应,`user`表示检查项白名单中的`user`策略白名单,`developer`表示检查项白名单中的开发者策略白名单。白名单的填写位置参考下表: 161 162 **表1** 主客体组合权限检查项白名单字段与报错对应关系 163 164 | 违反user策略 | 违反developer策略 | 写入字段位置 | 165 | -------- | -------- | -------- | 166 | 是 | 是 | user | 167 | 否 | 是 | developer | 168 | 是 | 否 | user,且需删除当前主客体在developer字段中的白名单 | 169 170- 方式二:修改不合理的策略,以满足要求,例如,更改方案,避免同时申请这两个权限。 171 172### 删除冗余的白名单 173 174当整改了不合理的权限组合配置后,删除了不合理的策略,但是未同时删除白名单时,也会触发编译报错,关键报错信息`remove the following unnecessary whitelists in rule 'xxx' part 'user'`,这里的`xxx`表示被拦截的检查项`name`,报错如下: 175```text 176 check rule 'execute and execute_no_trans' failed in whitelist file 'perm_group_whitelist.json' 177 remove the following unnecessary whitelists in rule 'execute and execute_no_trans' part 'user': 178 appspawn appspawn_exec 179 check rule 'execute and execute_no_trans' failed in whitelist file 'perm_group_whitelist.json' 180 remove the following unnecessary whitelists in rule 'execute and execute_no_trans' part 'developer': 181 appspawn appspawn_exec 182``` 183 184需要同时删除白名单,将`//base/security/selinux_adapter/sepolicy/`下的白名单文件`perm_group_whitelist.json`中的相关白名单删除,该文件如下: 185```text 186{ 187 "whitelist": [ 188 { 189 "name": "execute and execute_no_trans", 190 "user": [ 191 "appspawn appspawn_exec" 192 ], 193 "developer": [ 194 ] 195 } 196 ] 197} 198``` 199这里根据报错,要删除检查项`"execute and execute_no_trans"`下的`user`字段的白名单`"appspawn appspawn_exec"`,另外,其他冗余白名单报错的删除位置参考下表: 200 201**表2** 主客体组合权限检查项冗余白名单字段与报错对应关系 202| user白名单冗余 | developer白名单冗余 | 删除白名单字段位置 | 203| -------- | -------- | -------- | 204| 是 | 是 | user | 205| 否 | 是 | developer | 206| 是 | 否 | user | 207 208 209## 篡改高危进程基线检查 210 211### 检查说明 212 213OpenHarmony中存在一些高危进程,例如shell、console,这些进程的SELinux策略需要有管控,避免随意删除和新增,造成系统不可用或引入安全隐患。对于这些高危进程xx,其基线策略在`//base/security/selinux_adapter/sepolicy/`下的`xx.baseline`文件中。以sh基线为例,形式如下: 214```text 215(allow sh vendor_file (dir (search))) 216 217developer_only(` 218(allow sh system_lib_file (dir (search))) 219') 220``` 221 222其中被developer_only括起来的策略,表示该策略仅作为开发者模式下的基线;否则,表示该策略是user和开发者模式共用的基线。 223 224### 编译拦截 225 226新增和删除高危进程策略,都会触发编译报错,关键报错信息`check 'xxx' baseline in user mode failed`,xxx表示高危进程标签,报错如下: 227```text 228 check 'sh' baseline in user mode failed 229 expect rule: (allow sh vendor_file (dir ())); actual rule: (allow sh vendor_file (dir (search))) 230 There are two solutions: 231 1. Add the above actual rule to baseline file 'sh.baseline' under 'base/security/selinux_adapter/sepolicy' 232 2. Change the policy to satisfy expect rule 233 234 check 'sh' baseline in developer mode failed 235 expect rule: (allow sh vendor_file (dir ())); actual rule: (allow sh vendor_file (dir (search))) 236 There are two solutions: 237 1. Add the above actual rule to baseline file 'sh.baseline' under 'base/security/selinux_adapter/sepolicy' and add developer_only 238 2. Change the policy to satisfy expect rule 239``` 240 241### 拦截原因 242 243上述报错是因为,新增了sh的策略`"allow sh vendor_file:dir search;"`,对应的cil形式为`"(allow sh vendor_file (dir (search)))"`,同时违反了user和developer下的进程基线,期望的cil形式基线是`"(allow sh vendor_file (dir ()))"`。 244 245### 修复方法 246 247主要有两种修复方式: 248 249- 方式一:将报错中`"actual rule"`字段的cil策略,作为新基线添加到`//base/security/selinux_adapter/sepolicy/`下的基线文件`xx.baseline`中,`xx`为违反基线的进程标签。修改该基线文件需要评估安全性和合理性,审慎修改。其中,基线的填写位置参考下表: 250 251 **表3** 篡改高危进程基线检查基线更新位置与报错对应关系 252 | user基线报错 | developer基线报错 | 更新基线是否需要在developer_only内 | 253 | -------- | -------- | -------- | 254 | 是 | 是 | 否 | 255 | 否 | 是 | 是 | 256 | 是 | 否 | 将developer_only内的基线挪到外部 | 257 258- 方式二:修改不合理的策略,以满足要求,例如,更改方案,避免违反基线。 259 260### 删除冗余的基线 261 262当整改了不合理的基线策略后,删除了不合理的策略,但是未同时删除基线时,也会触发编译报错,关键报错信息`check 'xxx' baseline in user mode failed`,xxx表示高危进程标签,报错如下: 263``` 264 check 'sh' baseline in user mode failed 265 expect rule: (allow sh rootfs (dir (search))); actual rule: (allow sh rootfs (dir ())) 266 There are two solutions: 267 1. Add the above actual rule to baseline file 'sh.baseline' under 'base/security/selinux_adapter/sepolicy' 268 2. Change the policy to satisfy expect rule 269 270 check 'sh' baseline in developer mode failed 271 expect rule: (allow sh rootfs (dir (search))); actual rule: (allow sh rootfs (dir ())) 272 There are two solutions: 273 1. Add the above actual rule to baseline file 'sh.baseline' under 'base/security/selinux_adapter/sepolicy' and add developer_only 274 2. Change the policy to satisfy expect rule 275``` 276 277需要同时删除基线,将`//base/security/selinux_adapter/sepolicy/`下的基线文件`sh.baseline`中的相关基线删除。 278 279这里根据报错,要删除基线`"(allow sh rootfs (dir (search)))"`,另外,以符合`"actual rule"`,其他冗余基线报错的删除位置参考下表: 280 281**表4** 篡改高危进程基线检查冗余基线与报错对应关系 282| user基线冗余 | developer基线冗余 | 删除基线字段位置 | 283| -------- | -------- | -------- | 284| 是 | 是 | developer_only外 | 285| 否 | 是 | developer_only内 | 286| 是 | 否 | developer_only外 | 287 288## ioctl的权限策略检查 289 290### 检查说明 291 292涉及配置ioctl相关的SELinux策略时,除了配置allow规则以外,还需要根据avc日志对ioctl的ioctlcmd进行限制,否则会导致所有的ioctlcmd权限都被开放,不满足权限最小化原则。 293 294### 编译拦截 295 296配置的 allow 规则访问权限包含了 ioctl,但未限定 ioctl 权限参数时,会触发编译报错,关键报错信息`check ioctl rule in user mode failed.`,报错如下: 297```text 298 check ioctl rule in user mode failed. 299 violation list (allow scontext tcontext:tclass ioctl) 300 allow wifi_host data_service_el1_file:file ioctl; 301 allow wifi_host dev_hdfwifi:chr_file ioctl; 302 allow write_updater updater_block_file:blk_file ioctl; 303 please add "allowxperm" rule based on the above list. 304``` 305 306### 拦截原因 307 308仅添加`allow scontext tcontext:tclass ioctl`规则会导致主体有对tcontext:tclass所有ioctl的权限,权限过大被编译拦截,需添加具体的allowxperm对ioctl权限精细化管控,达到权限最小化。 309 310### 修复方法 311 312主要有两种修复方式: 313- 方式一:根据avc日志对ioctl的ioctlcmd进行限制。例如,有下面的avc日志: 314 ```text 315 #avc: denied { ioctl } for pid=1 comm="init" path="/data/app/el1/bundle/public" dev="mmcblk0p11" ino=652804 ioctlcmd=0x6613 scontext=u:r:init:s0 tcontext=u:object_r:data_app_el1_file:s0 tclass=dir permissive=0 316 ``` 317 根据该avc日志配置了允许ioctl的SELinux策略: 318 ```text 319 allow init data_app_el1_file:dir { ioctl }; 320 ``` 321 同时,还需要根据avc日志中的`ioctlcmd=0x6613`字段,在相同user或开发者模式基线下添加allowxperm,进一步限制ioctl的开放范围: 322 ```text 323 allowxperm init data_app_el1_file:dir ioctl { 0x6613 }; 324 ``` 325 326- 方式二:将拦截日志中的 "scontext tcontext tclass" 字符添加到`//base/security/selinux_adapter/sepolicy/`下白名单 `ioctl_xperm_whitelist.json` 中,修改该白名单需要评估合理性。 327 拦截日志中 `user mode` 表示该策略是user和开发者模式共用的基线,另外 `developer mode` 则表示该策略仅作为开发者模式下的基线,相应添加到白名单列表中。 328 ```text 329 { 330 "whitelist": { 331 "user": [ 332 "wifi_host data_service_el1_file file" 333 ], 334 "developer": [ 335 ] 336 } 337 } 338 ``` 339 340 341## permissive 主体类型的权限检查 342 343### 检查说明 344 345增加 permissive 的主体类型,会放开其访问所有客体的权限,不满足权限最小化原则。 346 347### 编译拦截 348 349在策略文件中增加 `permissive scontext;` 后,会触发编译报错,关键报错信息 `check permissive rule in user mode failed.`,报错如下: 350```text 351 check permissive rule in user mode failed. 352 violation list (scontext): 353 sa_subsys_dfx_service 354 There are two solutions: 355 1. Add the above list to whitelist file 'permissive_whitelist.json' under 'base/security/selinux_adapter/sepolicy' in 'user' mode. 356 2. Change the policy to avoid violating rule. 357``` 358 359### 拦截原因 360 361规则中存在新增的 permissive 主体类型。 362 363### 修复方法 364 365主要有两种修复方式: 366- 方式一:删除不必要的 permissive 定义。 367- 方式二:添加主体类型scontext到 `//base/security/selinux_adapter/sepolicy/` 下白名单 `permissive_whitelist.json` 中,修改该白名单需要评估合理性。 368 拦截日志中 `user mode` 表示该策略是user和开发者模式共用的基线,另外 `developer mode` 则表示该策略仅作为开发者模式下的基线,相应添加到白名单文件。 369 ```text 370 { 371 "whitelist": { 372 "user": [ 373 "sa_subsys_dfx_service" 374 ], 375 "developer": [ 376 ] 377 } 378 } 379 ```