Android Security Bulletin Analysis (April 2021)

2021-04-01 security patch level vulnerability details

Framework

CVE-2021-0400

  • 在使用紧急呼叫服务时,不信任模拟位置的返回。在Android里面允许用户在开发者选项中“选择模拟位置信息应用”,授予一个第三方应用模拟位置的权限,这样系统就会从这个来源获取位置坐标信息。该问题由Google的Soonil Nagarkar发现。

CVE-2021-0426

  • statsd遥测进程中的LogEvent模块,在parsePrimaryFieldFirstUidAnnotation函数中存在一个堆缓冲区溢出导致的越界写。该问题由360 Alpha Lab的Xiaobo Xiang和Guang Gong发现。
  • Android 9包含statsd遥测功能,statsd可收集应用使用情况、电池和进程统计信息以及崩溃数据。这些数据会经过分析并用于改进产品、硬件和服务。
  • 关于statsd的更多信息详见:https://source.android.google.cn/devices/architecture/modular-system/statsd

CVE-2021-0427

  • statsd遥测进程中的LogEvent模块,在parseExclusiveStateAnnotation函数中存在一个堆缓冲区溢出导致的越界写。该问题由360 Alpha Lab的Xiaobo Xiang和Guang Gong发现。
  • 0426和0427这两个漏洞新增了一些测试用例,可以有助于理解这两个问题,位于:
// frameworks/base/cmds/statsd/tests/LogEvent_test.cpp
TEST(LogEventTest, TestExclusiveStateAnnotationAfterTooManyFields)
TEST(LogEventTest, TestUidAnnotationAfterTooManyFields)
TEST(LogEventTest, TestAttributionChainEndIndexAfterTooManyFields)
TEST(LogEventTest, TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation)

CVE-2021-0432

  • statsd遥测进程中的StatsPullerManager模块,在ForceClearCache和ClearCacheIfNecessary函数中操作了共享资源kAllPullAtomInfo但未使用锁,可能在Puller注册或取消注册过程中存在条件竞争问题。该问题由GWP-ASan发现。

CVE-2021-0438

  • WindowManagerService中有一个hidden的flag名为NO_INPUT_CHANNEL,允许应用程序创建一个没有输入通道的窗口。在Android R以前,这会导致窗口被错误地配置一个FLAG_OBSCURED标志,导致窗口覆盖攻击,具体效果待实测。该问题由Google的Rob Carr发现。

CVE-2021-0439

  • PowerManagerService中的setPowerBoostWithHandle函数和setPowerModeWithHandle函数,由于缺失边界检查导致越界写问题。
static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) {
    // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
    // Need to increase the array size if more boost supported.
    static std::array<std::atomic<HalSupport>,
                      static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT /* 1 */) + 1>
            boostSupportedArray = {HalSupport::UNKNOWN};
    
    // Quick return if boost is not supported by HAL
    // *** 传入一个负数可绕过大于1的校验,导致后续写boostSupportedArray数组溢出 ***
    if (boost > Boost::DISPLAY_UPDATE_IMMINENT /* 1 */ || 
        boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
            ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
            return;
    }

    if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
        bool isSupported = false;
        handle->isBoostSupported(boost, &isSupported);
        // *** OOB Write ***
        boostSupportedArray[static_cast<int32_t>(boost)] = isSupported ? HalSupport::ON : HalSupport::OFF;
        if (!isSupported) {
            ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
                  toString(boost).c_str());
            return;
        }
    }
    
    auto ret = handle->setBoost(boost, durationMs);
    processPowerHalReturn(ret.isOk(), "setPowerBoost");
}
  • Boost的定义
enum class Boost : int32_t {
  INTERACTION = 0,
  DISPLAY_UPDATE_IMMINENT = 1,
  ML_ACC = 2,
  AUDIO_LAUNCH = 3,
  CAMERA_LAUNCH = 4,
  CAMERA_SHOT = 5,
};
  • setPowerModeWithHandle的问题是一样的
static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) {
    // Android framework only sends mode upto DISPLAY_INACTIVE.
    // Need to increase the array if more mode supported.
    static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
            modeSupportedArray = {HalSupport::UNKNOWN};

    // Quick return if mode is not supported by HAL
    // *** 传入一个负数可绕过大于9的校验,导致后续写modeSupportedArray数组溢出 ***
    if (mode > Mode::DISPLAY_INACTIVE ||
        modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
            ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
            return false;
    }

    if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
        bool isSupported = false;
        handle->isModeSupported(mode, &isSupported);
        // *** OOB Write ***
        modeSupportedArray[static_cast<int32_t>(mode)] = isSupported ? HalSupport::ON : HalSupport::OFF;
        if (!isSupported) {
            ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
            return false;
        }
    }

    auto ret = handle->setMode(mode, enabled);
    processPowerHalReturn(ret.isOk(), "setPowerMode");
    return ret.isOk();
}
  • Mode的定义
enum class Mode : int32_t {
  DOUBLE_TAP_TO_WAKE = 0,
  LOW_POWER = 1,
  SUSTAINED_PERFORMANCE = 2,
  FIXED_PERFORMANCE = 3,
  VR = 4,
  LAUNCH = 5,
  EXPENSIVE_RENDERING = 6,
  INTERACTIVE = 7,
  DEVICE_IDLE = 8,
  DISPLAY_INACTIVE = 9,
  AUDIO_STREAMING_LOW_LATENCY = 10,
  CAMERA_STREAMING_SECURE = 11,
  CAMERA_STREAMING_LOW = 12,
  CAMERA_STREAMING_MID = 13,
  CAMERA_STREAMING_HIGH = 14,
};

CVE-2021-0442

  • 在InputApplicationHandle中,仅更新Native层的InputApplicationHandle一次,以避免条件竞争问题。该问题由小米的Mingming Wang发现。

CVE-2021-0443

  • 在多用户切换时终止截图进程,以避免信息泄露。该问题由Elliott Brooks发现。

CVE-2021-0444

  • 在QuickContact的onActivityResult中,将不再返回Intent的data。该问题由Oversecured Inc.的Sergey Toshin发现。

Media Framework

CVE-2021-0437

  • DrmPlugin中的mPlayPolicy由于条件竞争问题可被Double Free。该问题由Chong Wang发现。

CVE-2021-0436

  • CryptoPlugin中存在一个整数溢出问题,会导致越界读造成信息泄露。该问题由Chong Wang发现。

CVE-2021-0471

  • CryptoPlugin中存在一个整数溢出问题,会导致越界读造成信息泄露。该问题由Chong Wang发现。

System

CVE-2021-0430

  • NFC在处理MIFARE Classic卡的TLV时存在一个越界写入,可造成远程代码执行。该问题由Google Project Zero的Ned Williamson发现。

CVE-2021-0429

  • 在SensorService的HAL接口中存在一个UAF漏洞。该问题由GWP-ASan发现。

CVE-2021-0433

  • 为CompanionDeviceManager配置HIDE_NON_SYSTEM_OVERLAY_WINDOWS权限,防止悬浮窗覆盖。

CVE-2021-0446

  • 为vCard联系人导入流程配置HIDE_NON_SYSTEM_OVERLAY_WINDOWS权限,防止悬浮窗覆盖。

CVE-2021-0431

  • 在蓝牙AVRC模块中,使用calloc而不是malloc进行内存分配,以保证初始化时会以0填充缓冲区,防止信息泄露。该问题由L.O. Team的Cusas发现。

CVE-2021-0435

  • 在蓝牙AVRC模块中,使用calloc而不是malloc进行内存分配,以保证初始化时会以0填充缓冲区,防止信息泄露。该问题由L.O. Team的Cusas发现。

2021-04-05 security patch level vulnerability details

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注