[编辑]Policy编译
在SEAndroid中有关policy的相关源文件都在源码目录external/sepolicy中,在Android.mk文件中描述了相关编译过程,首先会使用m4预处理器将sepolicy中的所有相关文件整合成一个源文件plicy.conf,然后通过checkpolicy 编译器将policy.conf策略源文件编译成sepolicy.24的二进制策略文件(24为策略版本号)。checkpolicy编译器的所有源文件都在external/checkpolicy目录中,编译完成的二进制策略文件会在系统启动时被加载到内核中在权限检测时使用,而在系统启动时为一些系统文件添加安全上下文则是依据另外两个文件file_contexts和seapp_contexts实现。
[编辑]SEAndroid中的安全上下文介绍
SEAndroid的安全上下文共有4个部分组成分别为user、role、type、sensitivity,以u:object_r:system_data_file:s0为例:
user:安全上下文的第一列为user,在SEAndroid中的user只有一个就是u。
role:第二列表示role,在SEAndroid中的role有两个,分别为r和object_r。
type:第三列为type,SEAndroid中共定义了139种不同的type。
sensitivity:第四列是专为MLS访问机制所添加的安全上下文的扩展部分,格式为sensitivity[:category list][- sensitivity[:category list]],例如s0 - s15:c0.c1023,其中s0之后的内容可以不需要,冒号后面的内容是category,sensitivity和category组合一起声明了当前的安全级别,“-”号左右分别标识了安全级别的最低和最高,这一列的参数将在MLS约束检查时用到,“15”、“1023”表示了sensitivity和category的最大值,这一参数可在Android.mk中定义。
[编辑]Transition
某个程序被执行时,其相应的进程会处在相应的domain中,但当程序根据需要又执行了另一个程序时,进程就需要根据type transition规则进行domain transition,从而使新进程能顺利访问到相关文件。
[编辑]domain transition
完成domain transition需要满足5个条件,当进程需要进行domain切换时就会检测切换前和切换前和切换后两个domain是否满足这5个条件。
- 声明可执行文件为相应 domain 的“接入点“文件
这是通过allow语句显式声明主体对客体具有entrypoint权限完成,以下列出了全部SEAndroid中出现的声明:
以下的第三列部分就是声明的”接入点“文件,有了这个声明后第三列的type就成为了”接入点“文件。
allow adbd rootfs:file entrypoint; allow bluetoothd bluetoothd_exec:file { entrypoint read execute }; allow dbusd dbusd_exec:file { entrypoint read execute }; allow debuggerd debuggerd_exec:file { entrypoint read execute }; allow drmserver drmserver_exec:file { entrypoint read execute }; allow gpsd gpsd_exec:file { entrypoint read execute }; allow installd installd_exec:file { entrypoint read execute }; allow keystore keystore_exec:file { entrypoint read execute }; allow mediaserver mediaserver_exec:file { entrypoint read execute }; allow netd netd_exec:file { entrypoint read execute }; allow qemud qemud_exec:file { entrypoint read execute }; allow rild rild_exec:file { entrypoint read execute }; allow servicemanager servicemanager_exec:file { entrypoint read execute }; allow shell shell_exec:file { entrypoint read execute }; allow shell shell_exec:file { entrypoint read execute }; allow surfaceflinger surfaceflinger_exec:file { entrypoint read execute }; allow su su_exec:file { entrypoint read execute }; allow ueventd rootfs:file entrypoint; allow vold vold_exec:file { entrypoint read execute }; allow wpa wpa_exec:file { entrypoint read execute }; allow zygote zygote_exec:file { entrypoint read execute };
- 许可用户进程能够执行“接入点”文件
通过allow语句显式声明需要进行domain切换的主体必须对”接入点“文件拥有execute权限,以下列出了在SEAndroid中全部相关部分:
allow init bluetoothd_exec:file { getattr open read execute }; allow init dbusd_exec:file { getattr open read execute }; allow init debuggerd_exec:file { getattr open read execute }; allow init drmserver_exec:file { getattr open read execute }; allow init gpsd_exec:file { getattr open read execute }; allow init installd_exec:file { getattr open read execute }; allow init keystore_exec:file { getattr open read execute }; allow init mediaserver_exec:file { getattr open read execute }; allow init netd_exec:file { getattr open read execute }; allow init qemud_exec:file { getattr open read execute }; allow init rild_exec:file { getattr open read execute }; allow init servicemanager_exec:file { getattr open read execute }; allow adbd shell_exec:file { getattr open read execute }; allow init shell_exec:file { getattr open read execute }; allow init surfaceflinger_exec:file { getattr open read execute }; allow shell su_exec:file { getattr open read execute }; allow init vold_exec:file { getattr open read execute }; allow init wpa_exec:file { getattr open read execute }; allow init zygote_exec:file { getattr open read execute };
- 许可两个 domain 之间的切换
通过allow语句显式声明发生切换的两个domain之间必须拥有transition或dyntransition权限,以下列出了全部SEAndroid中出现部分:
allow init bluetoothd:process transition; allow init dbusd:process transition; allow init debuggerd:process transition; allow init drmserver:process transition; allow init gpsd:process transition; allow init installd:process transition; allow init keystore:process transition; allow init mediaserver:process transition; allow init netd:process transition; allow init qemud:process transition; allow init rild:process transition; allow init servicemanager:process transition; allow adbd shell:process transition; allow init shell:process transition; allow init surfaceflinger:process transition; allow shell su:process transition; allow init vold:process transition; allow init wpa:process transition; allow init zygote:process transition; allow zygote system:process dyntransition; allow zygote appdomain:process dyntransition;
- 许可进程的角色和新domain之间的关联
SEAndroid通过安全上下文中的role实现了“基于角色的访问控制”(RBAC – Role Based Access Control)。进程安全上下文中的role的作用就是限制了该进程能够转换到的新的domain。在SEAndroid中只有两个role,分别命名为r,object_r。通过使用规则role r types domain来将角色r与属性domain进行关联,这样就能确保所有安全上下文中角色为r的主体可以转换为在domain属性中的有的type(多个同一类type可以归到一个属性(attribute)中)。
- 使能 domain 切换
通过type_transition语句声明来使能domain切换,以下列出了部分type_transition规则,第二列是转换前的domain,第三列是”接入点“文件,第四列则是转换后的domain。
type_transition init bluetoothd_exec:process bluetoothd; type_transition init dbusd_exec:process dbusd; type_transition init debuggerd_exec:process debuggerd; type_transition init drmserver_exec:process drmserver; type_transition init gpsd_exec:process gpsd; type_transition gpsd gps_data_file:sock_file gps_socket; type_transition init installd_exec:process installd; type_transition init keystore_exec:process keystore; type_transition init mediaserver_exec:process mediaserver; type_transition init netd_exec:process netd; type_transition init qemud_exec:process qemud; type_transition init rild_exec:process rild; type_transition init servicemanager_exec:process servicemanager; type_transition adbd shell_exec:process shell; type_transition init shell_exec:process shell; type_transition init surfaceflinger_exec:process surfaceflinger; type_transition shell su_exec:process su; type_transition system wifi_data_file:sock_file system_wpa_socket; type_transition init vold_exec:process vold; type_transition init wpa_exec:process wpa; type_transition init zygote_exec:process zygote;
[编辑]type transition
type_transition 规则被用在Domain Transition中 或者确定新创建对象的标签,以重载其默认的、从父目录(containing directory)所继承的标签。通常情况下新创建文件的标签和其父目录的标签一致,但是可以使用 type_transition 规则为其指定特定的标签。
[编辑]标记安全上下文的方式
[编辑]基于策略语句标记
[编辑]默认标记
[编辑]程序请求标记
[编辑]初始SID标记
[编辑]基于不同文件系统的各类标记机制
[编辑]基于扩展属性(fs_use_xattr)
[编辑]基于任务(fs_use_task)
[编辑]基于转换(fs_use_trans)
[编辑]一般方式(genfscon)
[编辑]关于Policy的三个核心源文件介绍
[编辑]file_contexts
这一文件主要罗列了启动时为系统的5个部分添加的安全上下文的内容,这5个部分分别为device(/dev目录下)、system(/system目录下)、data(/data目录下)、efs(/efs目录下)、catch(/catch目录下)。安全上下文的添加是以匹配左边的目录正则表达式实现,这一过程是在系统启动并运行了initramfs文件装载了二进制policy文件并为rootfs文件系统添加完安全上下文后进行的。
以下是file_contexts文件的全部内容:
########################################### # Root # # Nothing required since it is initramfs and implicitly labeled # by genfscon rootfs in ocontexts. # ########################## # Devices # /dev(/.*)? u:object_r:device:s0 /dev/akm8973.* u:object_r:akm_device:s0 /dev/accelerometer u:object_r:accelerometer_device:s0 /dev/alarm u:object_r:alarm_device:s0 /dev/android_adb.* u:object_r:adb_device:s0 /dev/ashmem u:object_r:ashmem_device:s0 /dev/audio.* u:object_r:audio_device:s0 /dev/binder u:object_r:binder_device:s0 /dev/block(/.*)? u:object_r:block_device:s0 /dev/block/loop[0-9]* u:object_r:loop_device:s0 /dev/block/ram[0-9]* u:object_r:ram_device:s0 /dev/block/mtdblock5 u:object_r:radio_device:s0 /dev/cam u:object_r:camera_device:s0 /dev/console u:object_r:console_device:s0 /dev/cpuctl(/.*)? u:object_r:cpuctl_device:s0 /dev/device-mapper u:object_r:dm_device:s0 /dev/full u:object_r:full_device:s0 /dev/graphics(/.*)? u:object_r:graphics_device:s0 /dev/input(/.*) u:object_r:input_device:s0 /dev/kmem u:object_r:kmem_device:s0 /dev/log(/.*)? u:object_r:log_device:s0 /dev/mem u:object_r:kmem_device:s0 /dev/modem.* u:object_r:radio_device:s0 /dev/mtd(/.*)? u:object_r:mtd_device:s0 /dev/mtd/mtd5 u:object_r:radio_device:s0 /dev/mtd/mtd5ro u:object_r:radio_device:s0 /dev/mtp_usb u:object_r:mtp_device:s0 /dev/pn544 u:object_r:nfc_device:s0 /dev/ptmx u:object_r:ptmx_device:s0 /dev/pvrsrvkm u:object_r:powervr_device:s0 /dev/qemu_.* u:object_r:qemu_device:s0 /dev/kmsg u:object_r:kmsg_device:s0 /dev/null u:object_r:null_device:s0 /dev/nvhdcp1 u:object_r:video_device:s0 /dev/nvmap u:object_r:nv_device:s0 /dev/nvhost-.* u:object_r:nv_device:s0 /dev/random u:object_r:random_device:s0 /dev/s3c-jpg u:object_r:camera_device:s0 /dev/s3c-mem u:object_r:camera_device:s0 /dev/s3c-mfc u:object_r:graphics_device:s0 /dev/snd(/.*)? u:object_r:audio_device:s0 /dev/socket u:object_r:socket_device:s0 /dev/socket/bluetooth u:object_r:bluetooth_socket:s0 /dev/socket/dbus_bluetooth u:object_r:bluetooth_socket:s0 /dev/socket/dbus u:object_r:dbus_socket:s0 /dev/socket/dnsproxyd u:object_r:dnsproxyd_socket:s0 /dev/socket/installd u:object_r:installd_socket:s0 /dev/socket/keystore u:object_r:keystore_socket:s0 /dev/socket/netd u:object_r:netd_socket:s0 /dev/socket/property_service u:object_r:property_socket:s0 /dev/socket/qemud u:object_r:qemud_socket:s0 /dev/socket/rild u:object_r:rild_socket:s0 /dev/socket/rild-debug u:object_r:rild_debug_socket:s0 /dev/socket/vold u:object_r:vold_socket:s0 /dev/socket/wpa_eth[0-9] u:object_r:wpa_socket:s0 /dev/socket/wpa_wlan[0-9] u:object_r:wpa_socket:s0 /dev/socket/zygote u:object_r:zygote_socket:s0 /dev/spdif_out.* u:object_r:audio_device:s0 /dev/tegra.* u:object_r:video_device:s0 /dev/tty[0-9]* u:object_r:tty_device:s0 /dev/ttyS[0-9]* u:object_r:serial_device:s0 /dev/uinput u:object_r:input_device:s0 /dev/urandom u:object_r:urandom_device:s0 /dev/vcs[0-9a-z]* u:object_r:vcs_device:s0 /dev/video[0-9]* u:object_r:video_device:s0 /dev/zero u:object_r:zero_device:s0 ############################# # System files # /system(/.*)? u:object_r:system_file:s0 /system/bin/ash u:object_r:shell_exec:s0 /system/bin/mksh u:object_r:shell_exec:s0 /system/bin/sh -- u:object_r:shell_exec:s0 /system/bin/app_process u:object_r:zygote_exec:s0 /system/bin/servicemanager u:object_r:servicemanager_exec:s0 /system/bin/surfaceflinger u:object_r:surfaceflinger_exec:s0 /system/bin/drmserver u:object_r:drmserver_exec:s0 /system/bin/vold u:object_r:vold_exec:s0 /system/bin/netd u:object_r:netd_exec:s0 /system/bin/rild u:object_r:rild_exec:s0 /system/bin/mediaserver u:object_r:mediaserver_exec:s0 /system/bin/dbus-daemon u:object_r:dbusd_exec:s0 /system/bin/installd u:object_r:installd_exec:s0 /system/bin/keystore u:object_r:keystore_exec:s0 /system/bin/debuggerd u:object_r:debuggerd_exec:s0 /system/bin/bluetoothd u:object_r:bluetoothd_exec:s0 /system/bin/wpa_supplicant u:object_r:wpa_exec:s0 /system/bin/qemud u:object_r:qemud_exec:s0 /system/xbin/su u:object_r:su_exec:s0 /system/vendor/bin/gpsd u:object_r:gpsd_exec:s0 ############################# # Data files # /data(/.*)? u:object_r:system_data_file:s0 /data/gps(/.*)? u:object_r:gps_data_file:s0 /data/dalvik-cache(/.*)? u:object_r:dalvikcache_data_file:s0 /data/anr(/.*)? u:object_r:anr_data_file:s0 /data/app(/.*)? u:object_r:apk_data_file:s0 /data/tombstones(/.*)? u:object_r:tombstone_data_file:s0 /data/local(/.*)? u:object_r:shell_data_file:s0 # Misc data /data/misc/bluetoothd(/.*)? u:object_r:bluetoothd_data_file:s0 /data/misc/bluetooth(/.*)? u:object_r:bluetooth_data_file:s0 /data/misc/keystore(/.*)? u:object_r:keystore_data_file:s0 /data/misc/vpn(/.*)? u:object_r:vpn_data_file:s0 /data/misc/systemkeys(/.*)? u:object_r:systemkeys_data_file:s0 /data/misc/wifi(/.*)? u:object_r:wifi_data_file:s0 # App sandboxes /data/data/.* u:object_r:app_data_file:s0 ############################# # efs files # /efs(/.*)? u:object_r:efs_file:s0 ############################# # Cache files # /cache(/.*)? u:object_r:cache_file:s0 ############################# # sysfs files # /sys/qemu_trace/process_name -- u:object_r:sysfs_writable:s0
[编辑]seapp_contexts
[编辑]policy.conf
policy.conf文件是在系统编译时期由m4预处理器将external/sepolicy目录下相关的10个文件整合而成的一个策略源文件,这一源文件集合了全部的安全策略规则。参与整合的10个文件如下所示:
- policy_capabilities
这一部分的内容列举了当前policy可实现的能力,全部内容如下:
# Enable new networking controls. policycap network_peer_controls; # Enable open permission check. policycap open_perms;
- initial_sids
初始sid提供了一种特殊的默认标记行为,初始sid适用于两种环境:在系统初始化策略还没有载入前的时间,以及当客体的安全上下文无效或安全上下文丢失时使用,initial_sids文件列出所有的初始sid,第二列的内容为这些sid的名字。 文件内容如下所示:
# FLASK # # Define initial security identifiers # sid kernel sid security sid unlabeled sid fs sid file sid file_labels sid init sid any_socket sid port sid netif sid netmsg sid node sid igmp_packet sid icmp_socket sid tcp_socket sid sysctl_modprobe sid sysctl sid sysctl_fs sid sysctl_kernel sid sysctl_net sid sysctl_net_unix sid sysctl_vm sid sysctl_dev sid kmod sid policy sid scmp_packet sid devnull # FLASK
- ocontexts
ocontexts文件中包含了对于初始sid的安全上下文分配, 以及针对不同的文件系统使用四种不同语法对其安全上下文进行的标记,以下是该文件的全部内容。
sid kernel u:r:kernel:s0 sid security u:object_r:kernel:s0 sid unlabeled u:object_r:unlabeled:s0 sid fs u:object_r:labeledfs:s0 sid file u:object_r:unlabeled:s0 sid file_labels u:object_r:unlabeled:s0 sid init u:object_r:unlabeled:s0 sid any_socket u:object_r:unlabeled:s0 sid port u:object_r:port:s0 sid netif u:object_r:netif:s0 sid netmsg u:object_r:unlabeled:s0 sid node u:object_r:node:s0 sid igmp_packet u:object_r:unlabeled:s0 sid icmp_socket u:object_r:unlabeled:s0 sid tcp_socket u:object_r:unlabeled:s0 sid sysctl_modprobe u:object_r:unlabeled:s0 sid sysctl u:object_r:proc:s0 sid sysctl_fs u:object_r:unlabeled:s0 sid sysctl_kernel u:object_r:unlabeled:s0 sid sysctl_net u:object_r:unlabeled:s0 sid sysctl_net_unix u:object_r:unlabeled:s0 sid sysctl_vm u:object_r:unlabeled:s0 sid sysctl_dev u:object_r:unlabeled:s0 sid kmod u:object_r:unlabeled:s0 sid policy u:object_r:unlabeled:s0 sid scmp_packet u:object_r:unlabeled:s0 sid devnull u:object_r:null_device:s0 # Label inodes via getxattr. fs_use_xattr yaffs2 u:object_r:labeledfs:s0; fs_use_xattr jffs2 u:object_r:labeledfs:s0; fs_use_xattr ext2 u:object_r:labeledfs:s0; fs_use_xattr ext3 u:object_r:labeledfs:s0; fs_use_xattr ext4 u:object_r:labeledfs:s0; fs_use_xattr xfs u:object_r:labeledfs:s0; fs_use_xattr btrfs u:object_r:labeledfs:s0; # Label inodes from task label. fs_use_task pipefs u:object_r:pipefs:s0; fs_use_task sockfs u:object_r:sockfs:s0; # Label inodes from combination of task label and fs label. # Define type_transition rules if you want per-domain types. fs_use_trans devpts u:object_r:devpts:s0; fs_use_trans tmpfs u:object_r:tmpfs:s0; fs_use_trans devtmpfs u:object_r:device:s0; fs_use_trans shm u:object_r:shm:s0; fs_use_trans mqueue u:object_r:mqueue:s0; # Label inodes with the fs label. genfscon rootfs / u:object_r:rootfs:s0 # proc labeling can be further refined (longest matching prefix). genfscon proc / u:object_r:proc:s0 # selinuxfs booleans can be individually labeled. genfscon selinuxfs / u:object_r:selinuxfs:s0 genfscon cgroup / u:object_r:cgroup:s0 # sysfs labels can be set by userspace. genfscon sysfs / u:object_r:sysfs:s0 genfscon inotifyfs / u:object_r:inotify:s0 genfscon vfat / u:object_r:sdcard:s0 genfscon debugfs / u:object_r:debugfs:s0 genfscon fuse / u:object_r:sdcard:s0 # portcon statements go here, e.g. # portcon tcp 80 u:object_r:http_port:s0
- security_classes
系统中文件/资源的数量有数百万甚至书千万之多,但是类型固定。为了便于定义Object的访问权限,把系统中所有资源划分为若干类(class),可以给同一类资源的所有实例定义一组相同的访问权限。SEAndroid中共定义了83个class。
- access_vectors
- attributes
在SEAndroid中将一组具有共性的type集合归类为一个属性(attribute),SEAndroid中共有17中属性。使用 attribute 可以在开发时有效地减少类似规则的数目,并且可以“一劳永逸”地针对某种 type 指定它对某类 attribute 的能力。在allow语句中既可以直接使用type也可以使用attribute进行规则声明。
- users
- roles
SEAndroid中的roles文件非常简单,文件内容如下: 它定义了角色r和关联了角色r与属性domain。
role r; role r types domain;
- te