android binder驱动层

ServiceManager本身也实现为一个Server对象。

这似乎形成了一个互相矛盾的现象:

  1. 通过ServiceManager我们才能拿到Server的标识
  2. ServiceManager本身也是一个Server。

解决这个矛盾的办法其实也很简单:Binder机制为ServiceManager预留了一个特殊的位置。这个位置是预先定好的,任何想要使用ServiceManager的进程只要通过这个特定的位置就可以访问到ServiceManager了(而不用再通过ServiceManager的接口)。

在Binder驱动中,有一个全局的变量:

static struct binder_node *binder_context_mgr_node;

这个变量指向的就是ServiceManager。

当有进程通过ioctl并指定命令为BINDER_SET_CONTEXT_MGR的时候,驱动被认定这个进程是ServiceManager,binder_ioctl函数中对应的处理如下:

case BINDER_SET_CONTEXT_MGR:
	if (binder_context_mgr_node != NULL) {
		pr_err("BINDER_SET_CONTEXT_MGR already set\n");
		ret = -EBUSY;
		goto err;
	}
	ret = security_binder_set_context_mgr(proc->tsk);
	if (ret < 0)
		goto err;
	if (uid_valid(binder_context_mgr_uid)) {
		if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) {
			pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
			       from_kuid(&init_user_ns, current->cred->euid),
			       from_kuid(&init_user_ns, binder_context_mgr_uid));   
			ret = -EPERM;
			goto err;
		}
	} else
		binder_context_mgr_uid = current->cred->euid;
	binder_context_mgr_node = binder_new_node(proc, 0, 0);
	if (binder_context_mgr_node == NULL) {
		ret = -ENOMEM;
		goto err;
	}
	binder_context_mgr_node->local_weak_refs++;
	binder_context_mgr_node->local_strong_refs++;
	binder_context_mgr_node->has_strong_ref = 1;
	binder_context_mgr_node->has_weak_ref = 1;
	break;

在Binder驱动中,通过handle = 0这个位置来访问ServiceManager。例如,binder_transaction中,判断如果target.handler为0,则认为这个请求是发送给ServiceManager的,相关代码如下:

if (tr->target.handle) {
	struct binder_ref *ref;
	ref = binder_get_ref(proc, tr->target.handle, true);
	if (ref == NULL) {
		binder_user_error("%d:%d got transaction to invalid handle\n",
			proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_invalid_target_handle;
	}
	target_node = ref->node;
} else {
	target_node = binder_context_mgr_node;
	if (target_node == NULL) {
		return_error = BR_DEAD_REPLY;
		goto err_no_context_mgr_node;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值