主頁 > 移動端開發 > Android selinux知識點總結

Android selinux知識點總結

2020-11-15 12:16:36 移動端開發

1 Efuse and Dm-verity
1.1 Efuse - 對bootloader簽名
熔絲檔案:sec.dat

1)燒寫signed bootloader
2)將密匙檔案sec.dat燒寫入efuse
3)重啟設備,設備的bootROM會讀取efuse中的密匙pubk驗證bootloader
4)bootloader驗證通過,啟動,開始AVB驗證流程

1.2 編譯時關閉AVB
@ BoardConfig.mk
BOARD_AVB_ENABLE := false
BOARD_BUILD_DISABLED_VBMETAIMAGE := true

AndroidO之后沒有獨立的recovery.img,boot.img根據cmdline引數來決定mount哪個ramdisk,
如果有skip_initramfs引數,那么mount打包在system.img中的normal ramdisk;否則mount打包在boot.img中的recovery ramdisk,

引數BOARD_BUILD_SYSTEM_ROOT_IMAGE的配置決定是將normal ramdisk打包到boot.img中還是打包到system.img中,
打包到boot.img中:
BOARD_BUILD_SYSTEM_ROOT_IMAGE := false

打包到system.img中:
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true

1.3 AVB驗證流程
需要提前掛載磁區的fstab來自于commandline的androidboot.android_dt_dir

1)bootloader使用內置的OEM pubk驗證vbmeta.img,驗證通過后用vbmeta.img中的boot pubk驗證boot.img,如果驗證通過就啟動boot.img
2)init啟動后,init/fs_mgr使用vbmeta.img中的vendor pubk、system pubk、odm pubk驗證vendor.img、system.img、odm.img,驗證通過就mount,否則不會mount

Figure 1-1 Dm-verity的作業流程

編譯生成Metadata流程:
@ build/core/Makefile
->
@ build/tools/releasetools/build_image.py
->
BuildVerityTree() - 用來生成dm_verity需要的簽名資料
BuildVerityMetadata() - 生成Metadata資料
->
@ system/extras/verity/build_verity_metadata.py
->
build_verity_metadata()

1.4 Disable System Dm-verity
@ device/{ro.boot.hardware}/{ro.board.platform}/fstab.{ro.boot.hardware}
Change
/dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1,discard wait, avb
to
/dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1,discard wait

可以使用內核配置 CONFIG_DM_VERITY_HASH_PREFETCH_MIN_SIZE(默認大小為 128)來啟用 dm-verity 哈希預提取大小,該修改可提升啟動速度,

1.5 AndroidO userdebug版本運行時禁止dm-verity
AndroidO dm-verity disable flag存在于vbmeta.img(keystore磁區)中;而老版本是放置在system.img磁區的dm-verity metadata中,
1)在設定中打開OEM unlocking選項
2)在設定中打開USB debugging選項
3)adb reboot bootloader
4)fastboot flashing unlock和fastboot oem unlock
5)fastboot reboot
6)adb root
7)adb disable-verity
8)adb reboot
9)adb root
10)adb remount

1.6 AndroidO userdebug版本刷機時禁止dm-verity
AndroidO dm-verity disable flag存在于vbmeta.img(keystore磁區)中;而老版本是放置在system.img磁區的dm-verity metadata中,
1)在設定中打開OEM unlocking選項
2)在設定中打開USB debugging選項
3)adb reboot bootloader
4)fastboot flashing unlock和fastboot oem unlock
5)fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img
6)fastboot reboot
7)adb root
8)adb remount

2 Android selinux How-to
2.1 LSM(Linux Security Module)的五種實作
SELinux:Security Enhanced Linux,基于inode,Android當前使用的就是這種
SMACK:Simple Mandatory Access Control Kernel,基于inode
Tomoyo:日本女人名“智代”,日本人實作的代碼,基于path
AppArmor:應用盔甲,AppArmor is installed by default in Ubuntu
Yama:來自梵文,中文名為“閻羅”,只處理ptrace和檔案鏈接

2.2 注釋
avc - Access Vector Cache
avd - Access Vector Decision,訪問向量決策
ssid - 主體的安全標識
tsid - 客體的安全標識
tclass - 客體安全型別
requested - 申請檢查的權限
auditdata - 附加的審計資料,主要產生審計日志,供內核kauditd和用戶auditd保存日志到磁盤中,當權限檢查失敗時,內核會列印審計不通過的log,參考另一篇文章Linux auditd

2.3 編譯時強制打開selinux
BOARD_KERNEL_CMDLINE += androidboot.selinux=enforcing

2.4 查看設備節點的sepolicy權限
ls -alZ /dev/kmsg

2.5 not_full_treble
如果遇到execute_no_trans無法通過編譯neverallow檢查,就需要用到這個宏

2.6 根據avc log自動生成Android Selinux策略
2.6.1 生成policy文本檔案
1)提取所有的avc log
adb shell "cat /proc/kmsg | grep avc" > avc_log.txt

or

adb shell
dmesg | grep avc > /dev/avc_log.txt
adb pull /dev/avc_log.txt .

2)使用audit2allow直接生成policy
sudo apt-get install policycoreutils
audit2allow -i avc_log.txt -o output_pol.te

vi output_pol.te

2.6.2 直接插入到sepolicy檔案中
adb shell
dmesg > /dev/kern_msg.txt
adb pull /dev/kern_msg.txt .

cat kern_msg.log | audit2allow -p out/target/product/<device>/root/sepolicy

2.7 打開關閉Sepolicy
需要android版本是usereng/eng

adb root
adb shell

關閉:
# setenforce 0
打開:
# setenforce 1

2.8 添加到啟動腳本中禁止security
on nonencrypted
# A/B update verifier that marks a successful boot.
exec - root cache -- /system/bin/update_verifier nonencrypted
class_start main
class_start late_start

in late_start script, add [setenforce 0]

2.9 查找用戶空間支持的所有權限字串
用戶空間宏定義
@ sepolicy/global_macros

內核空間權限字串
@ security/selinux/selinuxfs.c
security_load_policy()
->
@ security/selinux/include/classmap.h
struct security_class_mapping secclass_map[]; // 對應tclass,權限bitmap(每個權限占用一個32bit整數的1bit)

2.10 Dump sepolicy DB
@ security/selinux/ss/services.c

#include <linux/moduleparam.h>
static int oem_sepolicy_db_show(char *buffer, const struct kernel_param *kp)
{
unsigned i, j;
struct sidtab_node *cur;
char *context_name = NULL;
u32 length;

i = 0;
while (secclass_map[i].name) i++;

printk(KERN_DEBUG "(tclass_cnt, current_mapping_size, SIDTAB_SIZE) = "
"(%d, %d, %d)\n\n",
i, current_mapping_size, SIDTAB_SIZE);
// step1
if (!current_mapping) {
goto out;
}
for (i = 0; i < current_mapping_size; i++) {
printk("%d (value, num_perms, permission_bitmap) = (%d, %d",
i, current_mapping[i].value, current_mapping[i].num_perms);
if (!current_mapping[i].num_perms) {
printk(")\n");
continue;
} else {
printk(" - ");
}
for (j = 0; j < current_mapping[i].num_perms; j++) {
if (j == (current_mapping[i].num_perms - 1)) {
printk("%x", current_mapping[i].perms[j]);
} else {
printk("%x ", current_mapping[i].perms[j]);
}
}
printk(")\n");
}

// step2
printk("\n");
for (i = 0; i < SIDTAB_SIZE; i++) {
cur = sidtab.htable[i];
while (cur) {
if (context_struct_to_string(&(cur->context),
&context_name, &length) < 0)
continue;
printk("(%d %s)", cur->sid, context_name);
kfree(context_name);

cur = cur->next;
if (cur) {
printk(" ### ");
}
}
printk("\n");
}
out:
// no output log to userspace
return 0;
}

static struct kernel_param_ops oem_sepolicy_db_ops = {
.get = oem_sepolicy_db_show,
};
module_param_cb(oem_sepolicy_db, &oem_sepolicy_db_ops, NULL, 0600);
MODULE_PARM_DESC(oem_sepolicy_db, "show sepolicy db");

3 Abbreviations
avb:Android Verified Boot,用dm-verify驗證system磁區的完整性,用在Android 8.0之后的fstab中
AVC:Access Vector Cache
DAC:Discretionary Access Control,自主訪問控制
FRP:Factory Reset Protection
LSM:Linux Security Module

Appendix
audit2allow python demo for OEM

#
# audit2allow, translate avc log to .te file
# Author: George Tso
#
# usage
# dmesg | grep "avc" > /dev/avc.log
# adb pull /dev/avc.log .
# audit2allow avc.log avc.te

import re
import string
import sys

def write_outfile(outfile, hashmap):
for (hm_key, hm_value) in hashmap.items():
#{
allow_value = ''

hm_value.sort()

if (len(hm_value) == 1):
allow_line = hm_key + ' ' + hm_value[0] + ';' + '\n'
else:
for value in hm_value:
allow_value += ' ' + value
allow_line = hm_key + ' {' + allow_value + ' };' + '\n'

outfile.writelines(allow_line)
#}

def has_proc(line, proc):
e_list = line.split()
for e in e_list:
#{
if (e.find('scontext') > -1):
sub = e.split(':')
if (proc == sub[2]):
return True
else:
return False
#}
return False

def _generate_te(proc_list):
src = ''
tgt = ''
tclass = ''
got_tclass = False
hashmap = {}
got_key = False
repeat = False

outfile = open(sys.argv[2], 'w')
for proc in proc_list:
#{
outfile.writelines('\n\n===============' + proc + '================\n')
file = open(sys.argv[1], 'r')
for line in file.readlines():
#{
line = line.strip()
if not len(line) or line.startswith('#'):
continue

if (has_proc(line, proc) == False):
# not this process, continue
continue

# regular expression to extract {}
perm = re.findall(r'[{](.*?)[}]', line)
#print perm[0].strip()

e_list = line.split()
for e in e_list:
#{
if (e.find('scontext') > -1):
sub = e.split(':')
src = sub[2]
elif (e.find('tcontext') > -1):
sub = e.split(':')
tgt = sub[2]
elif (e.find('tclass') > -1):
sub = e.split('=')
tclass = sub[1]
got_tclass = True

if (got_tclass == True):
got_tclass = False

allow_key = 'allow' + ' ' + src + ' ' + tgt + ':' + tclass.strip()
allow_value = perm[0].lstrip().rstrip()
hm_key = ''
hm_value = []

for (hm_key, hm_value) in hashmap.items():
#{
if (hm_key == allow_key):
got_key = True
break;
#}

if (got_key == True):
got_key = False

for value in hm_value:
#{
if (value == allow_value):
repeat = True
break;
#}
if (repeat == False):
hm_value.append(allow_value)
hashmap[allow_key] = hm_value
repeat = False
else:
hm_value = []
hm_value.append(allow_value)
hashmap[allow_key] = hm_value

#} end of for e in e_list
#} end of for line in file.readlines()

write_outfile(outfile, hashmap)
hashmap.clear()
file.close()
#} for proc in proc_list
outfile.close()

def generate_te():
# STEP 1 - FIND ALL THE PROCESSES
proc_list = []
repeat = False

file = open(sys.argv[1], 'r')
for line in file.readlines():
#{
line = line.strip()
if not len(line) or line.startswith('#'):
continue

e_list = line.split()
for e in e_list:
#{
if (e.find('scontext') > -1):
sub = e.split(':')
for proc in proc_list:
#{
if (proc == sub[2]):
repeat = True;
break;
#}
if (repeat == False):
proc_list.append(sub[2])
repeat = False
break
#}
#}
file.close()
proc_list.sort()
print proc_list

# STEP 2 - GENERATE OUTPUT FILE
_generate_te(proc_list)

if __name__ == '__main__':
if (len(sys.argv) < 3):
print(sys.argv[0] + ' ' + '<input_file.log>' + ' ' + '<output_file.te>')
exit(0)
generate_te()

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/217223.html

標籤:其他

上一篇:九章演算法 | Google面試題:K數之和

下一篇:用 PyPy 讓你的 Python 代碼運行得更快!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more