Android Binder getCallingUid() getCallingPid()

Binder getCallingUid() getCallingPid() 返回?

  Android在进程间交互的时候,会使用Binder机制。在Binder交互过程中,通过Binder.getCallingUid()、Binder.getCallingPid()得到调用方的UID和进程PID。

    /**
     * Return the ID of the process that sent you the current transaction
     * that is being processed.  This pid can be used with higher-level
     * system services to determine its identity and check permissions.
     * If the current thread is not currently executing an incoming transaction,
     * then its own pid is returned.
     *
     * Warning: oneway transactions do not receive PID.
     */
    @CriticalNative
    public static final native int getCallingPid();

    /**
     * Return the Linux uid assigned to the process that sent you the
     * current transaction that is being processed.  This uid can be used with
     * higher-level system services to determine its identity and check
     * permissions.  If the current thread is not currently executing an
     * incoming transaction, then its own uid is returned.
     */
    @CriticalNative
    public static final native int getCallingUid();

  这俩函数的实现在android_util_Binder.cpp中

static jint android_os_Binder_getCallingPid()
{
    return IPCThreadState::self()->getCallingPid();
}

static jint android_os_Binder_getCallingUid()
{
    return IPCThreadState::self()->getCallingUid();
}

  IPCThreadState这个类对应着线程,

pid_t IPCThreadState::getCallingPid() const
{
    checkContextIsBinderForUse(__func__);
    return mCallingPid;
}
uid_t IPCThreadState::getCallingUid() const
{
    checkContextIsBinderForUse(__func__);
    return mCallingUid;
}

  所以现在就知道Binder.getCallingUid()、Binder.getCallingPid()得到的值了,就是对应的线程对应的IPCThreadState类对象的成员mCallingUid、mCallingPid的值。

mCallingUid mCallingPid在哪块赋值

Binder交互过程中协议命令

Binder交互过程中协议命令

  要知道mCallingUid mCallingPid在哪块赋值,需要知道Binder交互过程。在这块只需要知道有关mCallingUid、mCallingPid相关的代码。
  在BC_TRANSACTION命令中如下代码:

static void binder_transaction(struct binder_proc *proc,
			       struct binder_thread *thread,
			       struct binder_transaction_data *tr, int reply,
			       binder_size_t extra_buffers_size)
{
…………
	t->sender_euid = task_euid(proc->tsk);
…………
}

  其中t是binder_transaction指针,在这里将成员变量sender_euid 设置为调用进程的uid。在BC_TRANSACTION将事务数据设置完毕之后,会唤醒目标进程的线程进行处理相应事务,这块相关代码在binder_thread_read()中。

static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
…………
		trd->code = t->code;
		trd->flags = t->flags;
		trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid);

		t_from = binder_get_txn_from(t);
		if (t_from) {
			struct task_struct *sender = t_from->proc->tsk;

			trd->sender_pid =
				task_tgid_nr_ns(sender,
						task_active_pid_ns(current));
			trace_android_vh_sync_txn_recvd(thread->task, t_from->task);
		} else {
			trd->sender_pid = 0;
		}
…………
}

  在这里是在目标线程里执行代码的,trd是binder_transaction_data类指针,将它的成员变量sender_euid设置为t->sender_euid,这块的t->sender_euid就是上面赋值的调用方进程的uid。sender是调用方的进程描述符,trd->sender_pid在这块设置成调用方进程的pid。然后设置完事务数据之后,将cmd设置为BR_TRANSACTION或者BR_TRANSACTION_SEC_CTX之后,返回到用户态进行处理。
  用户态进程处理的代码如下:

status_t IPCThreadState::executeCommand(int32_t cmd)
{
…………
	case BR_TRANSACTION_SEC_CTX:
    case BR_TRANSACTION:
        {
        	…………
			const pid_t origPid = mCallingPid;
            const char* origSid = mCallingSid;
            const uid_t origUid = mCallingUid;
            …………
            mCallingPid = tr.sender_pid;
            mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
            mCallingUid = tr.sender_euid;
            …………
            error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags);
            …………
            mCallingPid = origPid;
            mCallingSid = origSid;
            mCallingUid = origUid;
            …………
					break;
				}
…………
}

  tr是binder_transaction_data对象,里面的数据就是在binder_thread_read()中设置的。在这里可以看到,在这里看到mCallingPid、mCallingUid被设置之后,就调用被调用对象的transact()方法。等到整个Bind处理完毕之后,就会将mCallingPid、mCallingUid设置为它们原来的值。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值