android中sepolicy, selinux学习笔记

android 权限 DAC MAC 


#if DAC(Discretionary Access Control) -- 自主访问控制
一、DAC(Discretionary Access Control) -- 自主访问控制


基于uid的访问权限控制
主体:uid/gid标记的进程
客体:uid/gid标记的文件
1)文件权限上下文


文件属性   user  group 大小  修改时间 文件名

-rw-r--r-- root     root         3567 1970-01-01 08:00 property_co
drwx------ root     root              2014-06-04 04:50 root
drwxr-x--- root     root              1970-01-01 08:00 sbin
lrwxrwxrwx root     root              2014-04-03 03:40 sdcard -> /ed/legacy
-rw-r--r-- root     root         7299 1970-01-01 08:00 seapp_context


文件类型
p 管道文件
d 目录文件
l 符号连接文件
- 普通文件
s socket文件
c 字符设备文件
b 块设备文件

d|rwx|r-x|--- /*除文件类型以外,每三个字符代表一种用户权限。前三位(所有者)中间
(所在组)后三位(其他组)。没有权限的用"-"表示
用8进制表示所以是三位二进制数。r-x == 101 == 5; rwx == 111 == 7*/


-----------------------------------
-rwsr-sr-t //s t

s位:如果设置s,那么s替换x位
SUID/SGID):在程序执行(exec)之后作为EUID的副本,用于进程切换自己的EUID时使用
SGID和SUID的存在意义在于,当一个非特权进程可以通过执行设置了SGID和SUID标志的程序,来获得特定权限。//加入hacker的进程H执行了这个文件,H进程既有root权限
例如su,当它没有设置SGID和SUID标志位的时候,实际上它是不能创建一个具有root权限的shell进程的。
t位:替换x位
sticky -- 用于文件夹,里面的文件只有创建者和拥有者可以删除。其他的id可以修改不能删
设置方法:
chmod 4775 filename // -rwsr-xr-x filename , 4是suid,2是sgid,1是sticky



android系统
-rwsr-sr-x root     root              u:object_r:su_exec:s0 su
-rwxr-s--- root     inet              u:object_r:system_file:s0 netcfg
linux
-rwsr-xr-x 2 root root 148024 2014-03-10 14:21 /usr/bin/sudo
-rwsr-xr-x 1 root root 42856 2011-02-14 17:11 /usr/bin/passwd
--- root root shadow

/tmp/new  777 selinux 
-----------------------------------
2)进程访问文件权限
(1)ps命令可以打出正在运行的进程。
(2)进程UID是root,可以访问所有的文件,是system/radio,只能访问对应id权限的文件。
(3)可以在shell/terminal输入id,查看当前所属的uid gid
3)su - switch uid //用户切换
对应的执行文件位置 /system/xbin/su
su argc argv //第一个参数是输入的参数数量(文件名本身是一个参数),第二个参数是一个指针数组,里面放了执行参数
/system/extras/su/su.c
#end


二、MAC(Mandatory Access Control) 强制访问控制 -- 任何访问都需要在sepolicy中进行配置
主要介绍基于type_domain的权限控制,
主体:Scontext标记的进程
客体:Scontext标记的文件

#if 1)selinux定义规范
1)selinux定义规范

(1)Security Cotext格式
进程(u:r:init_shell:s0   system(UID) 232  1 /system/bin/sh)    //必须设置source domain(shell) 对target domain(rootfs) 的访问权限,进程才能正常访问
文件(u:object_r:rootfs:s0 init.usb.rc)

user:role(RBAC):domain(TEAC,type):[多级安全MLS(可选项)]
一个user可以有多个role

(2)TE
[1]权限设定格式
##allow source_type(domain) target_type(domain):类目class perm_set ##
/sepolicy/security_classes //定义类目class,(包括文件(target),进程(source))
/sepolicy/access_vectors //向量表,定义了类目class的perm_set,这是权限
[2]将属性相似的链接到一个属性变量
#type命令的完整格式为:type type_id [alias alias_id,] [attribute_id]
将多个type类型,关联到一个attribute中,实现一个allow attribute 内部都起作用

(3)Role
#Android中只定义了一个role,名字就是r

(4)Lable
[1]最初的是在sepolicy/file_contexts 定义的上下文
[2]fork 出来的进程,需要将子进程的context进行转换,
file_type_auto_trans(domain, dir_type, file_type)宏
当domain域中的进程在某个Type为dir_type的目录中创建文件时,该文件的SContext应该是file_type

(5) domain迁移(trans)

type_transition init_t apache_exec_t : process apache_t;//init进程执行 apache_exec_t domain的文件时,子进程domain转到 apache

做这个迁移前,需要allow三个权限,所以放在下面的宏定义中实现

原domain启动一个新的进程,或者文件,转移domain
# domain_trans(olddomain, type, newdomain)
# domain_auto_trans(olddomain, type, newdomain)
# file_type_trans(domain, dir_type, file_type)
# file_type_auto_trans(domain, dir_type, file_type)

eg.
C:\Users\lmy>adb shell //adbd 进程,上下文却是shell
root@millet3g:/ # id
uid=0(root) gid=0(root) context=u:r:shell:s0

root@millet3g:/ # su shell (argc == 2 )
root@millet3g:/ $ id
uid=2000(shell) gid=2000(shell) context=u:r:su:s0


#end

#if 2)selinux初始化
system/core/init/init.c
selinux_initialize()->

#----------------------------------------------sepolicy 策略文件
int selinux_android_load_policy(void){
mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, NULL)//挂载一个文件系统,这个是sepolicy文件存放的位置‍
return selinux_android_reload_policy()‍
}


int selinux_android_reload_policy(void){
fd = open(path, O_RDONLY); //获取sepolicy 句柄‍
map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);//映射文件到进程,map就是对应的进程文件地址
rc = security_load_policy(map, sb.st_size);‍
}‍


int security_load_policy(void *data, size_t len){
fd = open(path, O_RDWR); //获取已经挂载的文件句柄‍//SELINUXMNT
ret = write(fd, data, len);//将sepolicy写进去‍,内核空间的selinuxfs ####### 策略放到内核了,检查也需要在内核检查
}‍
#-----------------------------------------------file_context lable
void selinux_init_all_handles(void){ //文件创建,进程启动的时候,会从这里找lable,然后进行标记
sehandle = selinux_android_file_context_handle();//file_context lable
sehandle_prop = selinux_android_prop_context_handle(); //property_context
}

//以后给文件打lable的时候,就是通过 sehanle sehandle_prop 来查找对应的权限的,如果找不到,那么标记为untrusted

‍struct selabel_handle* selinux_android_file_context_handle(void)-->‍ 
return file_context_open(); -->‍ get_selabel_handle(seopts);
h = selabel_open(SELABEL_CTX_FILE, &seopts[i], 1);
{
selabel_file_init
}

#end


#if 3)给文件打label
restorecon("/dev");
    restorecon("/dev/socket");
    restorecon("/dev/__properties__");{
if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0) //在file_context 找path
if (lsetfilecon(pathname, secontext) < 0) {} //对path的文件打label
} //基本所有文件都是由上面这两步打label


#end

#if 4)权限检查代码
先在avc(access vector cache) 查找权限,没有的话,继续在policy查找,如果找到,插入avc。找不到,返回denied
android/kernel/security/selinux/avc.c ***
android/external/libselinux/src/revision.c ***

(向上生长)
mtpg_open()
misc_open()
chrdev_open()
__dentry_open()
nameidata_to_filp()
do_last()  // ->may_open() -> error = inode_permission(inode, acc_mode);->这时候是在kernel的
path_openat()
do_filp_open()
do_sys_open()
SYSCALL_DEFINE3(open

(向下生长)
do_inode_permission() 
{return inode->i_op->permission(inode, mask);}
static struct security_operations selinux_ops = {
.name =  "selinux",
.inode_permission = selinux_inode_permission,
...
...
}
selinux_inode_permission() //kernel/security/selinux/hooks.c
avc_has_perm_noaudit() //找不到的话 -》 avc_compute_av()
avc_compute_av(){
security_compute_av(ssid, tsid, tclass, avd);//
avc_insert(ssid, tsid, tclass, avd);//插入到cache方便下次查找
}


/*inode_has_perm()
avc_has_perm_flags()*/



5)查看selinux log,解决denied

打印函数:selinux_avc_log

(1) *#9900# 查看avc_msg_xxxx.log, 搜denied /// log目录 》 proc/avc_msg
(2) avc:  denied  { add_name } for  pid=3523 comm="adbd" name="z1" scontext=u:r:adbd:s0 tcontext=u:object_r:system_file:s0 tclass=dir
(3) 那么 allow adbd system_file:dir add_name //可以解决

6)selinux应用
(1)C:\Users\lmy>adb shell
root@s3lite:/ # rm system/framework/services.odex
rm system/framework/services.odex
rm failed for system/framework/services.odex, Permission denied
#end


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值