这个binder面试题你会吗?-学员作业

背景:

前些天有学员朋友刚好带回来了一道关于binder相关的面试。当时看着其实感觉也没啥问题,并没啥难度,所以在vip群里也有学员朋友积极的进行回答。
在这里插入图片描述

面试题目如下:
有如下一个业务调用场景:
app调用wms接口,wms中处理又会调用到sf进程,请问说出在wms,sf中binder方法中getcalluid是谁?这个callinguid又是在哪设置的?
在这里插入图片描述
在这里插入图片描述

针对这个面试题大家可能都觉得不难,很多同学都可以答对认为是system_server的uid。

在但是也有同学提出做个实验发现就是uid为system_server,但是pid实际上是0.
在这里插入图片描述

所以针对这个getCallingPid到底是多少的问题反而成了最大的争议点。

多个版本验证getCallingPid

针对这个问题已经存在了各种争议,马哥也针对这个问题在不同的版本进行了验证,发现还确实是有差异的。

准备环境:

aosp14,aosp16这两个aosp的版本

打印部分添加:
这里以前些天豆包手机截图接口为案例
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

 @Override
    public void captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs,
            ScreenCapture.ScreenCaptureListener listener) {
            //打印callingpid和callinguid
        Slog.d(TAG, "captureDisplay " + Binder.getCallingUid() + " pid " + Binder.getCallingPid());
      
        ScreenCapture.LayerCaptureArgs layerCaptureArgs = getCaptureArgs(displayId, captureArgs);
        ScreenCapture.captureLayers(layerCaptureArgs, listener);

    }

在远端SurfaceFlinger中也进行打印
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

binder::Status SurfaceComposerAIDL::captureLayers(
        const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
     IPCThreadState* ipc = IPCThreadState::self();
    const int pid = ipc->getCallingPid();
    const int uid = ipc->getCallingUid();
    ALOGE("SurfaceComposerAIDL::captureLayers pid %d uid %d " ,pid,uid);       
    mFlinger->captureLayers(args, captureListener);
    return binderStatusFromStatusT(NO_ERROR);
}

但是两个aosp版本确实得出不同的结果。
aosp14版本日志:

12-24 11:32:38.648   341   606 E SurfaceFlinger:  SurfaceComposerAIDL::captureLayers pid 515  uid 1000

aosp16版本日志:

12-24 11:40:47.893   518  1285 E SurfaceFlinger: SurfaceComposerAIDL::captureLayers pid 0 uid 1000 
12-24 11:40:47.893   518  1285 E SurfaceFlinger: validateScreenshotPermissions pid 0 uid 1000 

可以看出确实在aosp16版本显示pid是0,但是对应uid是1000也就是system_server

但是真的aosp16版本都是pid为0吗?明显也不是哈,具体也可以看下面截图:
在这里插入图片描述可以看到其实也是有uid为1000但是pid不是0情况.

前置必学binder驱动相关知识:

那么要解决上面这个疑问就必须学习如下这些前置知识

mCallingPid,mCallingUid是在哪里赋值的呢?
frameworks/native/libs/binder/IPCThreadState.cpp
sender_pid这里可以看出是在IPCThreadState::executeCommand方法中由内核进行返回的。
所以这块要查到根本原因还是要去binder.c中进行进一步排查。

drivers/android/binder.c

		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;
		}

这块代码确实看到有设置成0和正常pid的,但是这块代码排查后,两个14,16版本都是一样的调用方式。
那么到底差异在哪呢?这部分就留给各位学员去探索一下,按照我上面限定的方法。

学员作业要求:

1、剖析出uid和pid是如何在kernel中被binder驱动进行设置的

2、解释什么场景调用pid就会设置为0

3、解释清楚为啥同样的captureDisplay接口,aosp14和aosp16会有差异。

原文参考:
https://mp.weixin.qq.com/s/gT7AN6sp3A_bcXeM9Ut7yQ

更多framework实战开发干货,请关注下面“千里马学框架”

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值