android IPC通信中的UID和PID识别 -》 clearCallingIdentity 的作用

本文深入探讨了IPC调用过程中,IPCThreadState对象如何维护进程的PID和UID,及其在权限检测中的关键作用。通过分析不同场景下mCallingPid和mCallingUid的保存对象,阐述了权限检测的机制。并介绍了用于切换调用方身份的clearCallingIdentity()和restoreCallingIdentity()函数,以及在实际应用中的案例。

 http://blog.youkuaiyun.com/windskier/article/details/6921672


IPCThreadState对象维护了2个变量

            pid_t               mCallingPid;

            uid_t               mCallingUid;

    从变量名称来看,这2个变量保存了进程的PID和UID,并且由于这两个变量由IPCThreadState对象维护,可见它们是与IPC相关的。具体它们保存的是IPC发送方的PID和UID还是当前进程的IPD和UID,视情况而定。

    在IPC调用过程中,被调用方需要知道调用方的UID和PID,以便被调用方用于权限检测;所以需要一种方式来提供调用方的UID和PID,因此上述2个变量的主要作用就是用于权限检测。

    那么我们想象一下,下面描述的情况下,mCallingPid和mCallingUid又应该保存谁的UID和PID?假如有2个进程process A和process B,我们站在process B的角度来分析,process A IPC调用process B, 而process B 又调用同样处于process B的Service的接口(尽管此时实际上不是远程调用,并且开发者是知道的,但是对于Binder调用机制来说,它本身并不知道当前的调用是否为远程调用,前几篇文章中有分析系统如何确定是否为远程调用,这个过程是在binder driver中实现的),那么此时mCallingPid和mCallingUid是不是应该保存process B的UID和PID?

1.       process B在被process A IPC调用时, process B需知道process A的UID和PID,来检查process A的访问权限,此时mCallingUid和mCallingPid保存的是process A的UID和PID。

2.       在IPC远程调用process B的过程中,process B的方法调用了同进程中的service的接口,process B既是调用方也是被调用方,虽然这个过程比较无聊,但是鉴于IPC过程的不透明性,因此process B仍然需要进行权限检测。

 

    前面的文章中分析过,binder driver会判断当前的Binder调用是否为远程调用,如果是同进程调用的话,BD就不会再向应用提供进程的PID和UID。因此在process B中需要显示的设置当前的PID和UID。

    为实现以上case, android提供了一组函数

    public static final native long clearCallingIdentity();

    public static final native void restoreCallingIdentity(long token);

    process B的方法调用了同进程中的service的接口前,clearCallingIdentity()方法会清除process A的UID和PID,重置为process B的UID和PID。

    process B的方法调用了同进程中的service的接口后,此时仍然处在process A远程调用process B方法的过程中,此时需要restore  process A的UID和PID。

    本文描述的case,虽然在application 开发中并不常见,但是在system_server中很常见,比如client调用ActivityManagerService的方法,而ActivityManagerService又调用了PackageManagerService的方法,并且ActivityManagerService和PackageManagerService均会运行在system_server进程中。

<think>我们正在讨论CarService与VHAL通信的安全性保障机制。根据引用[1][4],系统开发者(车厂/Tier1)需要实现定制VHAL,并可能对CarService进行客制化扩展。安全性是其中的重要考虑。 在Android Automotive中,CarService与VHAL通信的安全性主要通过以下机制实现: 1. **权限控制(Permission Control)**: - CarService中定义了车辆属性访问所需的权限,例如`android.car.permission.CONTROL_CAR_ENGINE`用于控制引擎状态。 - 在CarService的代码中,每次处理来自客户端的请求时,会检查调用者是否具备相应的权限。例如,在CarService的某个服务方法中,可能会调用`checkCallingPermission`方法进行权限校验。 - 引用[3]提到,Car API与CarService中的服务存在对应关系,因此每个服务都可以独立设置权限要求。 2. **进程间通信IPC)的安全机制**: - CarServiceVHAL运行在不同的进程(CarService在SystemServer进程,VHAL在native进程),它们通过HIDL或AIDL接口进行通信- Android系统本身为Binder IPC提供了安全特性,包括调用方身份(UID/PID)的验证,确保只有受信任的进程才能调用特定接口。 3. **VHAL层的访问控制**: - VHAL在实现时,会根据属性配置的访问权限(如`VEHICLE_PROPERTY_ACCESS_READ`,`VEHICLE_PROPERTY_ACCESS_READ_WRITE`)来限制操作。 - 每个车辆属性在定义时(通常在`vehicle.h`中)就指定了其访问权限,VHAL在收到设置属性的请求时会检查该请求是否符合权限要求。 4. **SELinux策略**: - Android的SELinux为各个进程定义了严格的安全策略。例如,只有特定的域(如car_service进程)才有权限与VHAL进程(运行在特定的hal_vehicle域)通信- 车厂在定制系统时,需要根据实际需求配置SELinux策略,确保仅有授权的进程可以访问VHAL。 5. **自定义安全扩展**: - 根据引用[1],车厂可能需要针对自家车型进行安全扩展。例如,增加额外的认证步骤(如要求输入PIN码)才能执行某些敏感操作(如远程启动引擎)。 具体到源码层面: - **权限检查示例(CarService端)**: 在CarService中,每次处理设置车辆属性的请求时,会调用类似如下的代码: ```java // 伪代码,基于实际逻辑 public void setVehicleProperty(int propId, VehiclePropValue value) { // 检查调用者是否具有该属性的写权限 String requiredPermission = mVehicleHal.getWritePermission(propId); if (requiredPermission != null) { mContext.enforceCallingOrSelfPermission(requiredPermission, "setVehicleProperty"); } // 调用VHAL接口 mVehicleHidl.set(value); } ``` - **VHAL层的访问控制(VHAL端)**: 在VHAL的实现中,会检查请求的属性是否允许当前操作。例如: ```cpp // 伪代码 StatusCode VehicleHalManager::set(const VehiclePropValue& value) { auto config = getConfig(value.prop); if (config == nullptr) { return StatusCode::INVALID_ARG; } // 检查写权限 if (!(config->access & VEHICLE_PROPERTY_ACCESS_WRITE)) { return StatusCode::ACCESS_DENIED; } // 进一步处理... } ``` 总结来说,CarService与VHAL通信的安全性建立在多层防护上:应用层权限检查、Android系统级的IPC安全机制、SELinux强制访问控制,以及VHAL内部的属性访问控制。这些机制共同确保了车辆关键操作的安全性[^1][^3][^4]。 §§相关问题§§ 1. 如何为自定义车辆属性添加权限控制? 2. SELinux策略如何配置以保护VHAL? 3. 车辆属性访问权限有哪些类型? </think>### CarService与VHAL通信安全性保障机制分析 在Android Automotive架构中,CarService与VHAL(Vehicle Hardware Abstraction Layer)的通信安全性通过多层防护机制实现,主要包含以下核心方案: #### 1. **权限控制系统(核心防护层)** - **属性级访问控制** 每个车辆属性(如引擎状态、车速)在`vehicle.h`头文件中预定义访问权限: ```cpp #define VEHICLE_PROPERTY_ACCESS_READ 0x01 #define VEHICLE_PROPERTY_ACCESS_WRITE 0x02 ``` - 敏感属性(如引擎控制)强制要求`WRITE`权限 - 权限检查位于`VehicleHalManager.cpp`: ```cpp StatusCode set(const VehiclePropValue& value) { if (!(config->access & VEHICLE_PROPERTY_ACCESS_WRITE)) { return StatusCode::ACCESS_DENIED; // 拒绝无权限操作 } } ``` - **CarService权限验证** CarService通过`CarPerMissionManager`校验调用方权限: ```java // CarService源码示例 public void setEngineState(boolean on) { mContext.enforceCallingPermission( "android.car.permission.CONTROL_CAR_ENGINE", "Engine control denied" ); mVehicleHidl.set(createPropValue(ENGINE_STATE, on)); } ``` 关键权限包括: - `CONTROL_CAR_ENGINE`:引擎控制 - `SPEED`:车速读取 - `ADAS_CONTROL`:辅助驾驶系统控制[^1][^3] #### 2. **通信层安全机制** - **Binder IPC加固** CarService与VHAL通过HIDL/AIDL接口通信时: - 启用`Binder.clearCallingIdentity()`验证调用来源 - 使用`SELinux`策略限制访问域: ```sepolicy # 仅允许car_service域访问hal_vehicle域 allow car_service hal_vehicle:binder { call transfer }; ``` - **数据完整性保护** `VehiclePropValue`结构包含校验字段: ```cpp struct VehiclePropValue { int32_t prop; // 属性ID int64_t timestamp; // 防止重放攻击 uint32_t status; // 状态校验位 float value; // 实际值 }; ``` #### 3. **运行时安全监控** - **异常行为检测** `CarWatchdogService`监控通信异常: ```java // CarWatchdogManager与CarWatchdogService协作 void monitor() { if (vhalResponseTime > THRESHOLD) { logSecurityEvent("VHAL响应超时"); } } ``` - **安全审计日志** 关键操作记录至`dmesg`: ``` adb shell dmesg | grep 'VHAL_SEC' # 输出示例: [VHAL_SEC] DENIED write attempt to ENGINE_STATE by uid=10123 ``` #### 4. **OEM扩展安全机制** 车厂可扩展以下安全功能[^1]: - **双因子认证**:敏感操作需PIN码+生物认证 - **驾驶模式感知**:行驶中禁用部分危险操作 - **加密总线**:CAN总线数据加密传输(如AES-128) #### 安全架构示意图 ```mermaid graph TD A[APP] -->|CarManager API| B(CarService) B -->|1.权限校验| C[CarPerMissionManager] C -->|2.SELinux策略| D[Binder IPC] D -->|3.属性访问控制| E[VHAL] E -->|4.总线加密| F[ECU] ``` ### 安全性设计特点 1. **纵深防御**:权限控制+通信加密+运行时监控 2. **最小特权原则**:属性级细粒度权限 3. **可审计性**:完整操作日志记录 4. **OEM可扩展**:支持车厂定制安全策略[^1][^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值