Selinux 之SeAndroid學(xué)習(xí)雜記

版權(quán)說明:本文為 開開向前沖 原創(chuàng)文章栅葡,轉(zhuǎn)載請注明出處茉兰;
注:限于作者水平有限,文中有不對的地方還請指教

1. SContext 安全上下文

根據(jù)SELinux規(guī)范欣簇,標(biāo)準(zhǔn)的SContext字符串格式為:

user:role:type[:range]
  1. 查看進程的SContext :ps -Z规脸,
    ps -Z.png

    android 中進程的user 為 u,u在/external/sepolicy/users中定義熊咽;
    android 中進程的role 為 r莫鸭,r在/external/sepolicy/roles中定義;
    type 是進程的domain type横殴,一般是在進程對應(yīng)的te中指定被因,例如進程/system/bin/sh對應(yīng)的te文件在/external/sepolicy/shell.te中有 type shell, domain, mlstrustedsubject;
    [:range]代表可選衫仑,這里是s0氏身;這里不做詳解;
------> /external/sepolicy/users
user u roles { r } level s0 range s0 - mls_systemhigh;

------> /external/sepolicy/roles
role r;
role r types domain;

------> /external/sepolicy/shell.te
# Domain for shell processes spawned by ADB or console service.
type shell, domain, mlstrustedsubject;#指定shell 進程屬于domain域為shell
type shell_exec, exec_type, file_type;

  1. 查看文件的SContext:ls -Z


    ls -Z.png

    android 中進程的user 為 u惑畴,u在/external/sepolicy/users中定義;同進程一樣
    android 中文件的role 為 object_r航徙;android 中對于"死東西"(文件)都用object_r來表示role如贷;
    type 是文件的domain type;一般定義在/external/sepolicy/file.te中到踏,例如:type rootfs, fs_type;
    [:range]代表可選杠袱,這里是s0;

SeAndroid 編譯生效檢查:修改.te文件后窝稿,(前提是先編譯過android)remake android楣富,編譯成功后去到/out/target/product/xxxx/obj/ETC/sepolicy_intermediates/目錄下的policy.conf文件中看看你的修改是否有效;如果有效伴榔,則證明你的修改成功纹蝴,再make boot img庄萎,make boot img會將上述目錄中的sepolicy打包進boot.img,這樣刷boot.img就能驗證你的修改是否有效塘安;

Selinux核心思想就是最小權(quán)限原則糠涛,即主體對客體擁有的權(quán)限必須要通過allow語句定義才允許,否則的話兼犯,一切都是禁止的忍捡。

安全上下文中,只有 類型(Type)才是最重要的切黔,SELinux用戶砸脊、SELinux角色和安全級別都幾乎可以忽略不計的。正因為如此纬霞,SEAndroid安全機制又稱為是基于TE(Type Enforcement)策略的安全機制 ——摘自老羅

SEAndroid中凌埂,通常將標(biāo)注文件的安全上下文的類型稱為file_type,將標(biāo)注進程的安全上下文的類型稱為domain险领,每一個用于描述文件上下文的類型都將file_type 設(shè)置為其屬性侨舆,每一個用于描述進程安全上下文的類型都將domain設(shè)置為其屬性。
可以通過 type 語句實現(xiàn)將一個類型設(shè)置為另一個類型的屬性:

type printerserver, domain; #### 將domain 設(shè)置為printerserver的屬性
type persist_file, file_type;  #### 將file_type設(shè)置為persist_file的屬性

上述語句也表明用 printerserver描述的類型描述的是進程的安全上下文绢陌;
persist_file描述的類型描述的是文件的安全上下文挨下;

Linux Android系統(tǒng)中第一個啟動的進程是init進程。Init進程啟動過程中脐湾,執(zhí)行了很多的系統(tǒng)初始化工作臭笆,其中就包括初始化SEAndroid安全策略的工作,如下所示:init.c的main方法中會調(diào)用selinux_initialize方法初始化Selinux秤掌,可以通過修改is_enforcing的值(0或者1)來控制是否禁掉Selinux。

------>/system/core/init/init.c

static void selinux_initialize(void)
{
    if (selinux_is_disabled()) {
        return;
    }

    INFO("loading selinux policy\n");
    if (selinux_android_load_policy() < 0) {
        ERROR("SELinux: Failed to load policy; rebooting into recovery mode\n");
        android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
        while (1) { pause(); }  // never reached
    }

    selinux_init_all_handles();
    bool is_enforcing = selinux_is_enforcing();
    INFO("SELinux: security_setenforce(%d)\n", is_enforcing);
    security_setenforce(is_enforcing);//is_enforcing控制是否禁掉Selinux
}

下面說說/external/sepolicy/目錄下幾個重要的文件闻鉴;

attritbutes:屬性文件茵乱,定義了Selinux的屬性;

------> attritbutes
######################################
# Attribute declarations
# All types used for devices.
attribute dev_type;
# All types used for processes.
attribute domain; ###是不是很熟悉孟岛,我們在定義進程 Type 時都要指定這個屬性
# All types used for filesystems.
attribute fs_type;
......

device.te:描述Linux 設(shè)備 Type

------>device.te
# Device types
type device, dev_type, fs_type;
type alarm_device, dev_type, mlstrustedobject;
type adb_device, dev_type;
type ashmem_device, dev_type, mlstrustedobject;
type audio_device, dev_type;
type binder_device, dev_type, mlstrustedobject;
type block_device, dev_type;
type camera_device, dev_type;
type dm_device, dev_type;
......

file.te:描述Linux 文件 Type

------> file.te
# Persist file types
type persist_file, file_type;
type persist_data_file, file_type;
type persist_drm_file, file_type;
......

file_contexts:文件file_contexts通過正則表達式來描述系統(tǒng)文件的安全上下文瓶竭,Linux系統(tǒng)中一切皆文件,前面的device.te和file.te中都都有指定設(shè)備和文件Type渠羞,這些Type是怎么和系統(tǒng)中的設(shè)備和文件關(guān)聯(lián)的呢斤贰?就是通過file_contexts文件;

------> file_contexts
###################################
# data files
#
/data/connectivity(/.*)?                                            u:object_r:cnd_data_file:s0
/data/data_test(/.*)?                                               u:object_r:data_test_data_file:s0
/data/diag_log(/.*)?                                                u:object_r:diag_data_file:s0
/data/hlos_rfs(/.*)?                                                u:object_r:rfs_shared_hlos_file:s0
/data/camera(/.*)?                                                  u:object_r:camera_socket:s0
/data/system/sensors(/.*)?                                          u:object_r:sensors_data_file:s0
/data/time/*                                                        u:object_r:time_data_file:s0
/data/nfc(/.*)?                                                     u:object_r:nfc_data_file:s0
/data/system/perfd(/.*)?                                            u:object_r:mpctl_data_file:s0
......

根據(jù)SELinux規(guī)范次询,完整的 allow 相關(guān)的語句格式為:

rule_name source_type target_type : class perm_set
allow zygote shell_data_file:dir search;###這句話表示允許Zygote 進程對shell_data_file類型的 dir 進行search荧恍;
這里的 dir 和 search稱為object class和perm set,即可以在object class對象上進行perm set操作屯吊;object class定義在security_classes中摹菠,perm set定義在access_vectors中;

security_classes:定義被保護的object class對象,例如file,dir猜扮,fd等;

------> security_classes
# Define the security object classes
# file-related classes
class filesystem
class file
class dir
class fd
class lnk_file
class chr_file
class blk_file
class sock_file
class fifo_file

access_vectors:定義security_classes中object class對象具有哪些perm set糟需;

------> access_vectors
#
# Define a common prefix for file access vectors.
#
common file
{
    ioctl
    read
    write
    create
    getattr
    setattr
    lock
    relabelfrom
    relabelto
    append
    unlink
    link
    rename
    execute
    swapon
    quotaon
    mounton
}
......

上面說明了可以對被保護的 file 進行ioctl read write create等操作;

mac_permissions.xml:

<?xml version="1.0" encoding="utf-8"?>
<policy>
    <!-- Platform dev key in AOSP -->
    <signer signature="@PLATFORM" >
      <seinfo value="platform" />
    </signer>

    <!-- All other keys -->
    <default>
      <seinfo value="default" />
    </default>
</policy>

文件mac_permissions.xml給不同簽名的App分配不同的seinfo字符串谷朝,例如洲押,在AOSP源碼環(huán)境下編譯并且使用平臺簽名的App獲得的seinfo為“platform”,使用第三方簽名安裝的App獲得的seinfo簽名為"default"圆凰。這里的setinfo并不是安全上下文的Type杈帐;但是系統(tǒng)會根據(jù)這個setinfo到external/sepolicy/seapp_contexts中去查找和和setinfo 對應(yīng)的類型;

seapp_contexts:根據(jù)setinfo查找對應(yīng)應(yīng)用的安全上下文 Type专钉;

------> seapp_contexts
# Input selectors:
#   isSystemServer (boolean)
#   user (string)
#   seinfo (string)
#   name (string)
#   path (string)
#   sebool (string)
# isSystemServer=true can only be used once.
# An unspecified isSystemServer defaults to false.
# An unspecified string selector will match any value.
# A user string selector that ends in * will perform a prefix match.
# user=_app will match any regular app UID.
# user=_isolated will match any isolated service UID.
# All specified input selectors in an entry must match (i.e. logical AND).
# Matching is case-insensitive.
#
# Precedence rules:
#     (1) isSystemServer=true before isSystemServer=false.
#     (2) Specified user= string before unspecified user= string.
#     (3) Fixed user= string before user= prefix (i.e. ending in *).
#     (4) Longer user= prefix before shorter user= prefix.
#     (5) Specified seinfo= string before unspecified seinfo= string.
#     (6) Specified name= string before unspecified name= string.
#     (7) Specified path= string before unspecified path= string.
#     (8) Specified sebool= string before unspecified sebool= string.
#
# Outputs:
#   domain (string)
#   type (string)
#   levelFrom (string; one of none, all, app, or user)
#   level (string)
# Only entries that specify domain= will be used for app process labeling.
# Only entries that specify type= will be used for app directory labeling.
# levelFrom=user is only supported for _app or _isolated UIDs.
# levelFrom=app or levelFrom=all is only supported for _app UIDs.
# level may be used to specify a fixed level for any UID.
#
isSystemServer=true domain=system_server
user=system domain=system_app type=system_app_data_file
user=bluetooth domain=bluetooth type=bluetooth_data_file
user=nfc domain=nfc type=nfc_data_file
user=radio domain=radio type=radio_data_file
user=shared_relro domain=shared_relro
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app
user=_app seinfo=platform domain=platform_app type=app_data_file
user=_app domain=untrusted_app type=app_data_file

這里我保留了文件的全部內(nèi)容挑童,文中注釋很重要;
前面mac_permisssions.xml 中指定使用平臺簽名的應(yīng)用setinfo 為platform跃须,所以在seapp_contexts中最匹配的一行為:

user=_app seinfo=platform domain=platform_app type=app_data_file

這樣就可以知道站叼,使用平臺簽名的App進程domain為“platform_app”,它的數(shù)據(jù)文件的file_type為“app_data_file”菇民。

第三方簽名的應(yīng)用的seinfo為 "default"尽楔,但是在seapp_contexts并沒有以 user=_app seinfo=default開頭的行,但是有一行最匹配:

user=_app domain=untrusted_app type=app_data_file

這樣就知道了第三方App進程的domain 為 "untrusted_app"第练,它的數(shù)據(jù)文件的file_type為"app_data_file"阔馋;

global_macros,te_macros:一些宏定義文件娇掏;

------> te_macros
# upon executing its binary.
define(`init_daemon_domain', `
domain_auto_trans(init, $1_exec, $1)
tmpfs_domain($1)
')
#####################################
# app_domain(domain)
# Allow a base set of permissions required for all apps.
define(`app_domain', `
typeattribute $1 appdomain;
# Label ashmem objects with our own unique type.
tmpfs_domain($1)
# Map with PROT_EXEC.
allow $1 $1_tmpfs:file execute;
')
......

property_contexts:和file_contexts類似呕寝,這里初始化屬性的安全上下文;

-----> property_contexts
##########################
# property service keys
#
#
net.rmnet               u:object_r:net_radio_prop:s0
net.gprs                u:object_r:net_radio_prop:s0
net.ppp                 u:object_r:net_radio_prop:s0
net.qmi                 u:object_r:net_radio_prop:s0
net.lte                 u:object_r:net_radio_prop:s0
net.cdma                u:object_r:net_radio_prop:s0
net.dns                 u:object_r:net_radio_prop:s0
sys.usb.config          u:object_r:system_radio_prop:s0
ril.                    u:object_r:radio_prop:s0
gsm.                    u:object_r:radio_prop:s0
persist.radio           u:object_r:radio_prop:s0
.......

還有很多的文件婴梧,這里就不逐一分析了壁涎,遇到問題就明白了,這里舉兩個例子志秃;
/external/sepolicy目錄下是Google 針對整個平臺的限制,一般都不會修改嚼酝;自己的修改一般都在/device/qcom/sepolicy目錄浮还;
這里針對qcom平臺:/device/qcom/sepolicy/

例1:為一個進程添加Selinux 訪問權(quán)限;

步驟如下:
1:在/device/qcom/sepolicy/common目錄下創(chuàng)建一個和進程名一樣的.te文件闽巩;例如hello進程對應(yīng)的hello.te钧舌;在hello.te中使用type聲明該進程的 domain Type担汤;

------> hello.te
type hello, domain; ### 聲明該進程的domain Type 為 hello
type hello_exec, exec_type, file_type; ###這里說明hello進程可執(zhí)行文件的 Type為hello_exec,
#### 這里需要去file_contexts中去配置相關(guān)類型洼冻;
init_daemon_domain(hello) ###必須實現(xiàn)
binder_use(hello)
binder_service(hello)

allow hello hello_service:service_manager add;###hello_service需要向service.te中注冊崭歧,
allow hello system_server:binder call;
allow hello platform_app:binder call;
allow hello device:sock_file write;
allow hello untrusted_app:binder call;
allow hello system_app:dir search;
allow hello system_app:file { open read getattr };
......

因為這里注冊的是Service 還需要去service.te和service_contexts中添加對應(yīng)內(nèi)容,如果不需要提供跨進程服務(wù)就不需要添加撞牢;

-------> service.te
......
type hello_service,   service_manager_type; ####聲明系統(tǒng)服務(wù)的Type 為hello_service,屬性為service_manager_type
......
------> service_contexts
......
servicePackageName   u:object_r:hello_service:s0   ####servicePackageName是服務(wù)的包名率碾,
### 這里和hello.te中的allow hello hello_service:service_manager add;有關(guān)
......
------> file_contexts
......
/system/bin/hello     u:object_r:hello_exec:s0 
### hello_exec用于hello.te中的type hello_exec, exec_type, file_type;中
......

2:將步驟1中的hello.te字符串添加到/device/qcom/sepolicy/下的Android.mk文件BOARD_SEPOLICY_UNION := \ 標(biāo)簽中編譯;

BOARD_SEPOLICY_UNION := \
                        ......
                        hello.te
                        ......

是不是很簡單屋彪,這樣我們就添加完成了Hello進程的訪問權(quán)限所宰;

例2:為一個文件添加訪問控制;

步驟1:由于是為文件添加訪問權(quán)限畜挥;所以我們需要聲明該文件的Type仔粥;文件Type 在需要在file.te和file_contexts中聲明;file_contexts中聲明該文件位置蟹但;

------> file.te 
#Hello data files /data/hello
......
type hello_data_file, file_type, data_file_type;
......

------> file_contexts
......
/data/hello(/.*)?                                               u:object_r:hello_data_file:s0
......

這樣我們就算是為文件添加了權(quán)限躯泰,對于這個文件,有哪些文件需要去訪問呢华糖?這里我們不妨假定為platform app需要訪問這個文件麦向;

接下來我們就在platform_app.te中添加相關(guān)權(quán)限;

------> platform_app.te
# allow access /data/hello/
......
allow platform_app hello_data_file:file { open getattr read };
allow platform_app hello_data_file:dir { search };
......

這樣我們就為一個文件添加了訪問控制缅阳;添加Linux 設(shè)備也是類似磕蛇,對于設(shè)備配置只是去device.te和file_contexts添加類似于文件類型的東西;因為Linux 一切皆文件十办,設(shè)備也是文件秀撇,所以需要在file_contexts中為指定路徑配置設(shè)備 Type;

到這里初步說明了一般在Android中會用到的Selinux 場景向族,很多深的東西還需要進一步研究呵燕;這里只是一個皮毛;

下面幾個不錯的博客件相;我也是參考他們的博客學(xué)習(xí)

深入理解SELinux 之SEAndroid
修改domain.te導(dǎo)致CTS不過解決方案-SELinux報錯修改篇
file_contexts.bin和file_contexts轉(zhuǎn)換工具再扭,支持7.0~8.0
老羅說Selinux
TE語言規(guī)則
TE規(guī)則

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市夜矗,隨后出現(xiàn)的幾起案子泛范,更是在濱河造成了極大的恐慌,老刑警劉巖紊撕,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罢荡,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機区赵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門惭缰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笼才,你說我怎么就攤上這事漱受。” “怎么了骡送?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵昂羡,是天一觀的道長。 經(jīng)常有香客問我各谚,道長紧憾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任昌渤,我火速辦了婚禮赴穗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膀息。我一直安慰自己般眉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布潜支。 她就那樣靜靜地躺著甸赃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冗酿。 梳的紋絲不亂的頭發(fā)上埠对,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音裁替,去河邊找鬼项玛。 笑死,一個胖子當(dāng)著我的面吹牛弱判,可吹牛的內(nèi)容都是我干的襟沮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼昌腰,長吁一口氣:“原來是場噩夢啊……” “哼开伏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起遭商,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤固灵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后劫流,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巫玻,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡暑认,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了大审。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡座哩,死狀恐怖徒扶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情根穷,我是刑警寧澤姜骡,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站屿良,受9級特大地震影響圈澈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尘惧,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一康栈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喷橙,春花似錦啥么、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疙剑,卻和暖如春氯迂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背言缤。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工嚼蚀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人轧简。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓驰坊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哮独。 傳聞我的和親對象是個殘疾皇子拳芙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 歷史 Android的安全模型是基于一部分應(yīng)用程序沙箱(sandbox)的概念, 每個應(yīng)用程序都運行在自己的...
    惡魔殿下_HIM閱讀 34,633評論 4 24
  • 深入理解SELinux SEAndroid SEAndroid是Google在Android 4.4上正式推出的一...
    神農(nóng)修行閱讀 7,344評論 1 7
  • 在external/sepolicy目錄 存放了很多SELinux的策略定義文件,在類似device/lge/ma...
    夏大王2019閱讀 2,587評論 0 0
  • 如果懷疑是sepolicy權(quán)限導(dǎo)致的問題皮璧,首先需要確認(rèn)是否真的是權(quán)限導(dǎo)致的舟扎。 確認(rèn)方法是:關(guān)閉SELinux,查看...
    祝三壯閱讀 10,309評論 0 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理悴务,服務(wù)發(fā)現(xiàn)睹限,斷路器譬猫,智...
    卡卡羅2017閱讀 134,628評論 18 139