关于Binder代理对象泄露的问题

116 阅读2分钟

问题背景(恶意App搞崩系统)​

想象一个客服中心(系统进程),用户(App)可以打电话来注册订阅通知。但有些恶意用户(或烂代码)在短时间内疯狂拨打客服电话注册,每次注册都会产生一个“通话记录”(BinderProxy对象)和一个“接线员”(BpBinder对象)。短时间内大量注册会导致客服中心被通话记录和接线员塞满,最终系统崩溃。


​问题核心(内存泄漏)​

  • ​BinderProxy​​(Java层):像“通话记录”,记录谁打了电话。
  • ​BpBinder​​(Native层):像“接线员”,真正处理通话请求。
  • 恶意App频繁注册 → 疯狂生成“通话记录”和“接线员” → 内存耗尽 → 系统卡死。

​解决方案(限制恶意注册)​

Android P 之后,系统引入了一个“流量管制器”:

  1. ​计数规则​​:记录每个用户(App的UID)注册的“接线员”(BpBinder)数量。

  2. ​阈值限制​​:

    • 设置两个水位线:高水位(比如100个)、低水位(比如80个)。
    • 当某个用户注册的接线员超过高水位 → 触发警报。
  3. ​处理措施​​:

    • 打印错误日志(记录谁在搞事情)。
    • 如果用户是普通App → 直接挂断电话并拉黑(杀掉进程)。
    • 如果用户是系统App → 放一马(但记录日志)。

​技术实现(代码逻辑)​

  1. ​创建接线员前的检查​​:

    • 系统维护一个“用户接线员数量表”(sTrackingMap)。
    • 每次创建接线员(BpBinder::create())时,检查该用户是否已超限。
  2. ​超限后的操作​​:

    • 标记用户为“超限”(LIMIT_REACHED_MASK)。
    • 触发回调函数(比如通知客服经理处理)。
  3. ​回调处理(以AMS为例)​​:

    • 打印错误日志:“用户XXX搞事情了!”
    • 非系统用户 → 直接终止(killUid),防止拖垮系统。

​通俗总结​

  • ​问题​​:恶意App通过“无限打电话”把系统内存占满。
  • ​解决​​:系统给每个App设定“最大通话次数”,超限就挂电话+拉黑。
  • ​效果​​:Android P 之后,这类内存泄漏问题被有效遏制,系统更稳定。

这样一来,即使有恶意App想搞破坏,系统也能像“智能客服”一样及时识别并阻止,保证其他正常用户的体验。