IPC binder
SEAndroid只允许adbd、appdomain、drmserver、mediaserver、surfaceflinger、system这些type或attribute通过servicemanager使用binder IPC。
SEAndroid只允许指定的客户端domain对指定的服务端domain使用binder IPC,如以下所列,第一列是指定的客户端domain,第二列是指定的服务端domain。
adbd, surfaceflinger trusted_app, appdomain appdomain, binderservicedomain appdomain, trusted_app drmserver, system mediaserver, binderservicedomain mediaserver, appdomain surfaceflinger, system system_app, appdomain system, binderservicedomain system, appdomain
SEAndroid只允许指定的客户端domain传送由服务端创建的binder references,如以下所列,第一列是指定的客户端domain,第二列是指定的服务端domain。
trusted_app, appdomain appdomain, binderservicedomain appdomain, trusted_app system_app, appdomain system, binderservicedomain system, appdomain
标 题: 【原创】SEAndroid之IPC
作 者: ansquad时 间: 2013-04-19,10:43:49
链 接: http://bbs.pediy.com/showthread.php?t=170027
SELinux在系统级增加了强制访问控制,每个VFS node均在Security Server的控制之中。IPC是系统的重要功能,未经授权的使用均会给系统带来安全隐患,所以本文重点对SEAndroid在IPC中安全功能进行分析,作为Android的主要通信工具socket和binder,在SEAndroid均增加了权限的控制,下面分别对两个进行简要的分析。
一、 binder
为了增加binder的权限控制,首先在kernel的policy中增加一个class,并且增加了几个方法,
代码:
{ "binder", { "impersonate", "call", "set_context_mgr", "transfer", "receive"} },
Call:该进程是否可以调用另一个进程
Set_context_mgr:是否可以将自己注册成Context Manager
Transfer:是否可以传递某类型的binder引用到其他进程
Receive:是否可以接收某类型binder引用
对binder调用规则的配置有些繁琐,所以在TE中使用宏进行配置binder_use、binder_call、binder_transfer、binder_service。相应的功能介绍在代码里已经注释的比较清晰,如:
代码:
# binder_call(clientdomain, serverdomain) # Allow clientdomain to perform binder IPC to serverdomain. define(`binder_call', ` # First we receive a Binder ref to the server, then we call it. allow $1 $2:binder { receive call }; # Receive and use open files from the server. allow $1 $2:fd use;')
allow servicemanager self:binder set_context_mgr;
allow servicemanager domain:binder { receive transfer };
配置表示了servicemanager可以将自己设置为context manager,并且它可以对所有domain执行receive和transfer的操作。
下面看一下驱动的实现流程。首先在security_ops中增加了4个操作函数
代码:
.binder_set_context_mgr = selinux_binder_set_context_mgr, .binder_transaction = selinux_binder_transaction, .binder_transfer_binder = selinux_binder_transfer_binder, .binder_transfer_file = selinux_binder_transfer_file,
代码:
static int selinux_binder_set_context_mgr(struct task_struct *mgr) { u32 mysid = current_sid(); u32 mgrsid = task_sid(mgr); return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER, BINDER__SET_CONTEXT_MGR, NULL); }
代码:
static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply) …… if (security_binder_transaction(proc->tsk, target_proc->tsk) < 0) { return_error = BR_FAILED_REPLY; goto err_invalid_target_handle; } ……
代码:
static int selinux_binder_transaction(struct task_struct *from, struct task_struct *to) { u32 mysid = current_sid(); u32 fromsid = task_sid(from); u32 tosid = task_sid(to); int rc; if (mysid != fromsid) { rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER, BINDER__IMPERSONATE, NULL); if (rc) return rc; } return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL, NULL); }
二、 socket
在SEAndroid中service sockets的权限同样受到管理。Init进程在创建service附属socket的同时,根据file_contexts查询当前socket的权限,并将信息加入到socket的security context中,启动后的权限如下所示:
代码:
srw------- system system u:object_r:installd_socket:s0 installd srw-rw-rw- root root u:object_r:keystore_socket:s0 keystore srw-rw---- root system u:object_r:netd_socket:s0 netd srw-rw-rw- root root u:object_r:property_socket:s0 property_service srw-rw---- root radio u:object_r:rild_socket:s0 rild
关于socket使用权限的配置可以简单的使用两个宏定义unix_socket_connect、unix_socket_send,他们分别对应着TCP和UDP类型的socket访问。
代码:
# unix_socket_connect(clientdomain, socket, serverdomain) # Allow a local socket connection from clientdomain via # socket to serverdomain. define(`unix_socket_connect', ` allow $1 $2_socket:sock_file write; allow $1 $3:unix_stream_socket connectto; ')
代码:
unix_socket_connect(adbd, vold, vold)