在做指纹的过程中遇到了很多权限设置的问题,sepolicy权限。
有需求需要db目录修改,由/data目录转到/data/app目录之后,结果出现生成不了db文件的问题。
在系统fingerprint.te里添加权限
allow fingerprintserver apk_data_file:dir {read write open ioctl execute search getattr add_name create_dir_perms};
allow fingerprintserver apk_data_file:file {read write open ioctl create_file_perms};
第一句意思是允许fingerprintserver类型对apk_data_file类型的目录(dir)执行 read 、 write 、open 等操作
第二句意思是允许fingerprintserver类型对apk_data_file类型的文件(file)执行 read 、 write 、open 等操作
由于db文件是在/data/app目录下,那么肯定是要对/data/app目录下的文件进行操作。
所以我们只要找一下/data/app所在的域
查看/data/app目录所在的域 , adb shell 进入data目录,并执行如下命令
root@XXX :/data # ls -Z
…
drwxrwx— system system u:object_r:system_data_file:s0 amit
drwxrwxr-x system system u:object_r:anr_data_file:s0 anr
drwxrwx–x system system u:object_r:apk_data_file:s0 app
drwx—— root root u:object_r:asec_image_file:s0 app-asec
drwxrwx–x system system u:object_r:system_data_file:s0 app-lib
…
可以看出来data目录下有很多子目录,这里列出了amit 、anr、app、app-asec、app-lib等子目录,
其中app目录所在的域为apk_data_file就是这么找的。
前提是我们知道谁即哪个进程操作了这个db,
本例中是fp_native_service访问db
知道谁操作了这个db可以用以下方法查找进程所在的域 , adb shell 然后作如下操作
root@XXX :ps -Z
…
u:r:drmserver:s0 drm 302 1 /system/bin/drmserver
u:r:mediaserver:s0 media 303 1 /system/bin/mediaserver
u:r:fingerprintserver:s0 system 258 1 /system/bin/fp_native_service
u:r:installd:s0 install 304 1 /system/bin/installd
u:r:keystore:s0 keystore 306 1 /system/bin/keystore
…
这里没有将所有进程都列出来,只列出了部分进程,
但可以看到fp_native_service所在的域是fingerprintserver
即fingerprintserver类型的进程要对apk_data_file类型的文件进行某些操作
即排查是哪个权限问题
kenel.log中关键错误信息如下 这里搜的是 avc: denied
[ 486.936152] (0)[286:logd.auditd]type=1400 audit(1420041749.210:15756): avc: denied { write } for pid=5927 comm=”fp_native_servi” name=”app” dev=”mmcblk0p22″ ino=425985 scontext=u:r:fingerprintserver:s0 tcontext=u:object_r:apk_data_file:s0 tclass=dir permissive=0
其实log里已经包含了所有问题了。
scontext=u:r:fingerprintserver:s0 tcontext=u:object_r:apk_data_file:s0 tclass=dir permissive=0
那怎么知道是不是sepolicy权限引起的问题
判断是否是sepolicy权限问题
adb shell 之后执行setenforce 0可以暂时去除sepolicy权限 (不用重启机器,而且重启之后权限又恢复成原来的了)
具体操作为:
sepolicy权限去除之后发现db文件可以生成了。说明是sepolicy权限的问题。
这个setenforce 0 后面的零是什么意思 (只能是0或者1)
usage: setenforce [ Enforcing | Permissive | 1 | 0 ]
setenforce 0 设置SELinux 成为Permissive模式 (不检测sepolicy权限,但是会将违反权限的操作记录到log)
setenforce 1 设置SELinux 成为Enforcing模式 (强制检测sepolicy权限)
查看进程拥有的selinux权限,adb shell 然后执行 ps -Z
LABEL USER PID PPID NAME
u:r:servicemanager:s0 system 260 1 /system/bin/servicemanager
u:r:vold:s0 root 261 1 /system/bin/vold
u:r:surfaceflinger:s0 system 262 1 /system/bin/surfaceflinger
u:r:init:s0 root 263 1 /system/bin/sh
u:r:kernel:s0 root 273 2 kauditd
u:r:ccci_fsd:s0 radio 274 1 /system/bin/ccci_fsd
u:r:ccci_mdinit:s0 system 275 1 /system/bin/ccci_mdinit
u:r:kernel:s0 root 277 2 kworker/3:2H
LABEL里
u:r:servicemanager:s0
查看文件拥有的selinux权限需要执行 ls -Z
root@XXX :/data # ls -Z
…
drwxrwx— system system u:object_r:system_data_file:s0 amit
drwxrwxr-x system system u:object_r:anr_data_file:s0 anr
drwxrwx–x system system u:object_r:apk_data_file:s0 app
drwx—— root root u:object_r:asec_image_file:s0 app-asec
drwxrwx–x system system u:object_r:system_data_file:s0 app-lib
…
\bootable\bootloader\lk\platform\mtXXXX\rules.mk
SELINUX_STATUS值代表的含义如下:
1:disabled (不检测权限)
2:permissive (警告模式运行,所有操作都被允许,但是如果违反权限会被记录到日志,目测就是kernel.log)
3:enforcing (强制检测)
sepolicy权限设置报错
ERROR: end of file in comment
这是由于文件最后加了 注释
Multiple same specifications for 这个是重复定义了。
allow factory powerctl_prop:property_service set;
allow factory ttyGS_device:chr_file { read write open ioctl};
allow factory ttyMT_device:chr_file { read write open ioctl};
allow factory irtx_device:chr_file { read write ioctl open };
allow factory devpts:chr_file { read write getattr ioctl };
文件名 | 归类 |
mac_permissions.xml | App进程 |
seapp_contexts | App数据文件 |
file_contexts | 系统文件 |
property_contexts | 系统属性 |
/*
rule_name:规则名,分别有allow,dontaudit,neverallow等
source_type:主要作用是用来填写一个域(domain)
target_type:类型
class:类别,主要有File,Dir,Socket,SEAndroid还有Binder等
perm_set:动作集
*/
rule_name source_type target_type:class perm_set
/*
用中文来表述是:允许factory域里的进程或服务
对类型为ttyMT_device的类别为文件(file)
执行open,read,write,ioctl权限
*/
allow factory ttyMT_device:chr_file { read write open ioctl};
/dev/ttyMT.* u:object_r:ttyMT_device:s0
type shell, domain
//定义一个类型,属于dev_type属性
type ttyMT_device, dev_type;
//属性dev_type在external/sepolicyattributes的定义如下
attribute dev_type;
type usb_device, dev_type, mlstrustedobject;
#定义httpd_user_content_t,并关联两个属性
type httpd_user_content_t, file_type, httpdcontent;
分成两条语句进行表述:
#定义httpd_user_content_t
type httpd_user_content_t;
#关联属性
typeattribute httpd_user_content_t file_type, httpdcontent;
# All types used for devices.
attribute dev_type;
# All types used for processes.
attribute domain;
# All types used for filesystems.
attribute fs_type;
# All types used for files that can exist on a labeled fs.
# Do not use for pseudo file types.
attribute file_type;
# All types used for domain entry points.
attribute exec_type;
# All types used for property service
attribute property_type;
# All service_manager types created by system_server
attribute system_server_service;
# All domains that can override MLS restrictions.
# i.e. processes that can read up and write down.
attribute mlstrustedsubject;
# All types that can override MLS restrictions.
# i.e. files that can be read by lower and written by higher
attribute mlstrustedobject;
# All domains used for apps.
attribute appdomain;
# All domains used for apps with network access.
attribute netdomain;
# All domains used for binder service domains.
attribute binderservicedomain;
[external/sepolicy/security_classes示例]
# file-related classes
class filesystem
class file #代表普通文件
class dir #代表目录
class fd #代表文件描述符
class lnk_file #代表链接文件
class chr_file #代表字符设备文件
......
# network-related classes
class socket #socket
class tcp_socket
class udp_socket
......
class binder #Android平台特有的binder
class zygote #Android平台特有的zygote
格式为:common common_name { permission_name ... }
common定义的perm set能被另外一种perm set命令class所继承
如:
common file {
ioctl read write create getattr setattr lock relabelfrom relabelto
append unlink link rename execute swapon quotaon mounton
class class_name [ inherits common_name ] { permission_name ... }
inherits表示继承了某个common定义的权限
注意,class命令它不能被其他class继承
继承一个common,如继承了file common
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
不继承任何common,如
class binder
{
impersonate
call
set_context_mgr
transfer
}
然后是一些特殊的配置文件:
a. external/sepolicy/attributes -> 所有定义的attributes都在这个文件
b. external/sepolicy/access_vectors -> 对应了每一个class可以被允许执行的命令
c. external/sepolicy/roles -> Android中只定义了一个role,名字就是r,将r和attribute domain关联起来
d. external/sepolicy/users -> 其实是将user与roles进行了关联,设置了user的安全级别,s0为最低级是默认的级别,mls_systemHigh是最高的级别
e. external/sepolicy/security_classes -> 指的是上文命令中的class,个人认为这个class的内容是指在android运行过程中,程序或者系统可能用到的操作的模块
f. external/sepolicy/te_macros -> 系统定义的宏全在te_macros文件
g. external/sepolicy/***.te -> 一些配置的文件,包含了各种运行的规则
/sys/devices/system/cpu(/.*)? u:object_r:sysfs_devices_system_cpu:s0
/sys/power/wake_lock -- u:object_r:sysfs_wake_lock:s0
/sys/power/wake_unlock -- u:object_r:sysfs_wake_lock:s0
/sys/kernel/uevent_helper -- u:object_r:usermodehelper:s0
/sys/module/lowmemorykiller(/.*)? -- u:object_r:sysfs_lowmemorykiller:s0
#############################
# asec containers
/mnt/asec(/.*)? u:object_r:asec_apk_file:s0
/mnt/asec/[^/]+/[^/]+\.zip u:object_r:asec_public_file:s0
#‘-b’ - Block Device ‘-c’ - Character Device
#‘-d’ - Directory ‘-p’ - Named Pipe
#‘-l’ - Symbolic Link ‘-s’ - Socket
#‘--’ - Ordinary file
/*
允许user_t对bin_t类型的文件和文件夹执行read,getattr操作
*/
allow user_t bin_t : { file dir } { read getattr };
/*
允许domain对exec_type,sbin_t类型的文件执行execute的动作
*/
allow domain { exec_type sbin_t } : file execute;
/*
允许user_t对bin_t类型的文件和文件夹执行所有操作
*/
allow user_t bin_t : { file dir } *;
/*
允许user_t对bin_t类型的文件和文件夹执行除了read,getattr以外的所有操作
*/
allow user_t bin_t : { file dir } ~{ read getattr };
/*
允许domain对exec_type类型的文件执行execute的动作,除了sbin_t以外
*/
allow domain { exec_type -sbin_t } : file execute;
type_transition source_type target_type : class default_type;
举个例子
type_transition init_t apache_exec_t : process apache_t;
#首先,你得让init_t域中的进程能够执行type为apache_exec_t的文件
allow init_t apache_exec_t : file execute;
#然后,你还得告诉SELiux,允许init_t做DT切换以进入apache_t域
allow init_t apache_t : process transition;
#最后,你还得告诉SELinux,切换入口(对应为entrypoint权限)为执行pache_exec_t类型的文件
allow apache_t apache_exec_t : file entrypoint;
type_transition passwd_t tmp_t : file passwd_tmp_t;
对应的必须有两个前提条件:
* The source domain needs permission to add file entries into the directory
这个process 必须有在这个目录下添加文件的权限.
* The source domain needs permission to create file entries
这个process 必须有在这个目录下创建以这个Security Context 为Label 的文件权限.
#定义domain_auto_trans宏,$1,$2等等代表宏的第一个,第二个....参数
define(`domain_auto_trans', `
# 先allow相关权限,domain_trans宏定义在后面
domain_trans($1,$2,$3)
# 然后设置type_transition
type_transition $1 $2:process $3;
')
#定义domain_trans宏。
define(`domain_trans', `
# SEAndroid在上述三个最小权限上,还添加了自己的一些权限
allow $1 $2:file { getattr open read execute };
allow $1 $3:process transition;
allow $3 $2:file { entrypoint read execute };
allow $3 $1:process sigchld;
dontaudit $1 $3:process noatsecure;
allow $1 $3:process { siginh rlimitinh };
')
#####################################
# file_type_auto_trans(domain, dir_type, file_type)
# Automatically label new files with file_type when
# they are created by domain in directories labeled dir_type.
#
define(`file_type_auto_trans', `
# Allow the necessary permissions.
file_type_trans($1, $2, $3)
# Make the transition occur by default.
type_transition $1 $2:dir $3;
type_transition $1 $2:notdevfile_class_set $3;
')
define(`file_type_trans', `
# Allow the domain to add entries to the directory.
allow $1 $2:dir ra_dir_perms;
# Allow the domain to create the file.
allow $1 $3:notdevfile_class_set create_file_perms;
allow $1 $3:dir create_dir_perms;
')
define(`x_file_perms', `{ getattr execute execute_no_trans }')
define(`r_file_perms', `{ getattr open read ioctl lock }')
define(`w_file_perms', `{ open append write }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
allow demo demo_device:chr_file rw_file_perms;