欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]SEAndroid之IPC

[原创]SEAndroid之IPC

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"} },

Impersonate:该进程是否可以代表另一个进程使用binder
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;')

对于TE文件只需简单配置即可,例如servicemanager:
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,

首先看一下第一个函数,其的实现原理就是去AVC中查询当前的sid是否设置了context_mgr的权限,如果未经授权,则禁止此次操作。
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);

}

对于transaction的控制也是类似,在binder_transaction中增加hook,用来检查本次调用的权限,其中也是同样在AVC中查询权限。
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);

}

调用AVC进行权限查询和其他hook是一致的,基本原理如下图所示,如果cache中未能查到,就会去security server中查询policy,并且cache起来。

二、        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;

')

对于规则的配置只需如下,他表示了adbd domain的subject可以通过vold_socket类型的socket访问vold的domain。
unix_socket_connect(adbd, vold, vold)

上传的附件 image002.jpg

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功