From edccc13510f05c4f2dc4c7dcd01d940ad16ece6b Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Fri, 3 May 2019 20:32:52 -0700 Subject: [PATCH] Disallow Blank App Package Name on Q and Later (This is a merge of http://go/wvgerrit/78105) The Widevine Android CDM should not allow itself to be instantiated without an app package name, as this breaks SPOID protection. Unfortunately, pathways exist prior to Android Q that allow this to happen, and we cannot break these devices by changing the behavior now. As such, we will only refuse to allow instantiation without an app package name on devices first launched with Q and later. This change also migrates the WVDrmFactory and its tests away from explicitly naming friend classes for individual test, in favor of the now-recommended "test peer" pattern. Bug: 65680731 Test: libwvdrmengine_hidl_test Test: CTS NativeMediaDrmClearkeyTest Change-Id: Icccd1d8b9972ef6ad7e5b0dbf2d37ec987656385 --- libwvdrmengine/include_hidl/WVDrmFactory.h | 4 ++- libwvdrmengine/src_hidl/WVDrmFactory.cpp | 17 ++++++++++++- .../test/unit/WVDrmFactory_test.cpp | 25 ++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/libwvdrmengine/include_hidl/WVDrmFactory.h b/libwvdrmengine/include_hidl/WVDrmFactory.h index 19720113..1a98fac0 100644 --- a/libwvdrmengine/include_hidl/WVDrmFactory.h +++ b/libwvdrmengine/include_hidl/WVDrmFactory.h @@ -43,8 +43,10 @@ struct WVDrmFactory : public IDrmFactory { static WVGenericCryptoInterface sOemCryptoInterface; static bool areSpoidsEnabled(); + static bool isBlankAppPackageNameAllowed(); + static int32_t firstApiLevel(); - friend class WVDrmFactoryTest_CalculatesSpoidUseCorrectly_Test; + friend class WVDrmFactoryTestPeer; }; extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name); diff --git a/libwvdrmengine/src_hidl/WVDrmFactory.cpp b/libwvdrmengine/src_hidl/WVDrmFactory.cpp index 1a87c9a7..bec96026 100644 --- a/libwvdrmengine/src_hidl/WVDrmFactory.cpp +++ b/libwvdrmengine/src_hidl/WVDrmFactory.cpp @@ -71,6 +71,13 @@ Return WVDrmFactory::createPlugin( return Void(); } + if (!isBlankAppPackageNameAllowed() && appPackageName.empty()) { + ALOGE("Widevine Drm HAL: Failed to create DRM Plugin, blank App Package " + "Name disallowed."); + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, plugin); + return Void(); + } + plugin = new WVDrmPlugin(getCDM(), appPackageName.c_str(), &sOemCryptoInterface, areSpoidsEnabled()); _hidl_cb(Status::OK, plugin); @@ -78,6 +85,14 @@ Return WVDrmFactory::createPlugin( } bool WVDrmFactory::areSpoidsEnabled() { + return firstApiLevel() >= 26; // Android O +} + +bool WVDrmFactory::isBlankAppPackageNameAllowed() { + return firstApiLevel() < 29; // Android Q +} + +int32_t WVDrmFactory::firstApiLevel() { // Check what this device's first API level was. int32_t firstApiLevel = android::base::GetIntProperty("ro.product.first_api_level", 0); @@ -87,7 +102,7 @@ bool WVDrmFactory::areSpoidsEnabled() { firstApiLevel = android::base::GetIntProperty("ro.build.version.sdk", 0); } - return firstApiLevel >= 26; // Android O + return firstApiLevel; } diff --git a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp index aacf0805..c1e8d57a 100644 --- a/libwvdrmengine/test/unit/WVDrmFactory_test.cpp +++ b/libwvdrmengine/test/unit/WVDrmFactory_test.cpp @@ -33,6 +33,12 @@ const uint8_t kUnknownUUID[16] = { 0x08,0xBC,0xEF,0x32,0x34,0x1A,0x9A,0x26 }; +class WVDrmFactoryTestPeer : public WVDrmFactory { + public: + using WVDrmFactory::areSpoidsEnabled; + using WVDrmFactory::isBlankAppPackageNameAllowed; +}; + TEST(WVDrmFactoryTest, SupportsSupportedCryptoSchemes) { WVDrmFactory factory; @@ -104,7 +110,7 @@ TEST(WVDrmFactoryTest, SupportsSupportedCryptoSchemeWithLevel) { } TEST(WVDrmFactoryTest, CalculatesSpoidUseCorrectly) { - WVDrmFactory factory; + WVDrmFactoryTestPeer factory; int32_t firstApiLevel = android::base::GetIntProperty("ro.product.first_api_level", 0); @@ -120,6 +126,23 @@ TEST(WVDrmFactoryTest, CalculatesSpoidUseCorrectly) { "WVDrmFactory calculated a different SPOID state than expected."; } +TEST(WVDrmFactoryTest, CalculatesBlankAppPackageNamePermissibilityCorrectly) { + WVDrmFactoryTestPeer factory; + + int32_t firstApiLevel = + android::base::GetIntProperty("ro.product.first_api_level", 0); + if (firstApiLevel == 0) { + // First API Level is 0 on factory ROMs, but we can assume the current SDK + // version is the first if it's a factory ROM. + firstApiLevel = + android::base::GetIntProperty("ro.build.version.sdk", 0); + } + bool shouldAllow = (firstApiLevel < 29); // Android Q + + EXPECT_EQ(shouldAllow, factory.isBlankAppPackageNameAllowed()) << + "WVDrmFactory calculated a different Blank App Package Name state than expected."; +} + } // namespace widevine } // namespace V1_2 } // namespace drm