Guard against double initialize am: 03f8d1b6f7
Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/16306734 Change-Id: Ie2628bdebded7e58474b54abebb58b3b4e7ff54e
This commit is contained in:
committed by
Automerger Merge Worker
commit
6864a04975
@@ -718,7 +718,7 @@ struct LevelSession {
|
|||||||
level1_.Name = (L1_##Name##_t)dlsym(level1_library_, QUOTE(Function)); \
|
level1_.Name = (L1_##Name##_t)dlsym(level1_library_, QUOTE(Function)); \
|
||||||
if (!level1_.Name) { \
|
if (!level1_.Name) { \
|
||||||
LOGW("Could not load L1 %s. Falling back to L3.", QUOTE(Function)); \
|
LOGW("Could not load L1 %s. Falling back to L3.", QUOTE(Function)); \
|
||||||
if (level1_.Terminate) level1_.Terminate(); \
|
if (level1_.Terminate) Level1Terminate(); \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@@ -740,7 +740,11 @@ class Adapter {
|
|||||||
public:
|
public:
|
||||||
using map_iterator = std::map<OEMCrypto_SESSION, LevelSession>::iterator;
|
using map_iterator = std::map<OEMCrypto_SESSION, LevelSession>::iterator;
|
||||||
|
|
||||||
Adapter() : level1_valid_(false), level1_library_(nullptr) {}
|
Adapter()
|
||||||
|
: level1_valid_(false),
|
||||||
|
level1_initialized_(false),
|
||||||
|
level1_failed_(false),
|
||||||
|
level1_library_(nullptr) {}
|
||||||
|
|
||||||
// The adapter is only destroyed on certain errors, or when the process
|
// The adapter is only destroyed on certain errors, or when the process
|
||||||
// dies. It is NOT deleted after each OEMCrypto_Terminate.
|
// dies. It is NOT deleted after each OEMCrypto_Terminate.
|
||||||
@@ -819,9 +823,23 @@ class Adapter {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult Level1Terminate() {
|
||||||
|
OEMCryptoResult result = OEMCrypto_SUCCESS;
|
||||||
|
if (level1_.Terminate && level1_initialized_) {
|
||||||
|
LOGE("L1 Terminate");
|
||||||
|
result = level1_.Terminate();
|
||||||
|
} else {
|
||||||
|
LOGE("L1 Terminate not needed");
|
||||||
|
}
|
||||||
|
level1_initialized_ = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void FallBackToLevel3() {
|
void FallBackToLevel3() {
|
||||||
|
Level1Terminate();
|
||||||
level1_ = FunctionPointers(); // revert to all null pointers.
|
level1_ = FunctionPointers(); // revert to all null pointers.
|
||||||
level1_valid_ = false;
|
level1_valid_ = false;
|
||||||
|
level1_failed_ = true;
|
||||||
// Note: if the function pointers are bad, we do not close the library and
|
// Note: if the function pointers are bad, we do not close the library and
|
||||||
// try again later. Instead, we permanently fall back to L3. This is a
|
// try again later. Instead, we permanently fall back to L3. This is a
|
||||||
// debatable choice: I decided the risk of a dlclose resource leak out
|
// debatable choice: I decided the risk of a dlclose resource leak out
|
||||||
@@ -833,6 +851,12 @@ class Adapter {
|
|||||||
if (metrics == nullptr) {
|
if (metrics == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (level1_failed_) {
|
||||||
|
// If we failed to initialize the level 1 library before, then we don't
|
||||||
|
// try again.
|
||||||
|
LOGE("Still falling back to L3.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
level1_valid_ = true;
|
level1_valid_ = true;
|
||||||
const uint32_t kMinimumVersion = 8;
|
const uint32_t kMinimumVersion = 8;
|
||||||
const uint32_t kMaximumVersion = 16;
|
const uint32_t kMaximumVersion = 16;
|
||||||
@@ -864,6 +888,7 @@ class Adapter {
|
|||||||
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INITIALIZE_L1);
|
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INITIALIZE_L1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
level1_initialized_ = true;
|
||||||
level1_.version = level1_.APIVersion();
|
level1_.version = level1_.APIVersion();
|
||||||
level1_.security_level = wvcdm::kSecurityLevelUninitialized;
|
level1_.security_level = wvcdm::kSecurityLevelUninitialized;
|
||||||
metrics->SetL1ApiVersion(level1_.version);
|
metrics->SetL1ApiVersion(level1_.version);
|
||||||
@@ -874,7 +899,7 @@ class Adapter {
|
|||||||
level1_.version, kMinimumVersion);
|
level1_.version, kMinimumVersion);
|
||||||
metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode(
|
metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode(
|
||||||
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_WRONG_L1_VERSION);
|
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_WRONG_L1_VERSION);
|
||||||
level1_.Terminate();
|
Level1Terminate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,7 +1021,6 @@ class Adapter {
|
|||||||
level1_.security_level = wvcdm::kSecurityLevelUnknown;
|
level1_.security_level = wvcdm::kSecurityLevelUnknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,7 +1107,7 @@ class Adapter {
|
|||||||
session_map_.clear();
|
session_map_.clear();
|
||||||
OEMCryptoResult result = Level3_Terminate();
|
OEMCryptoResult result = Level3_Terminate();
|
||||||
if (level1_valid_) {
|
if (level1_valid_) {
|
||||||
result = level1_.Terminate();
|
result = Level1Terminate();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1154,8 +1178,7 @@ class Adapter {
|
|||||||
if (!level1_.IsKeyboxOrOEMCertValid) {
|
if (!level1_.IsKeyboxOrOEMCertValid) {
|
||||||
// TODO(b/189989043): add metrics.
|
// TODO(b/189989043): add metrics.
|
||||||
LOGE("L1 invalid function pointers. Falling back to L3");
|
LOGE("L1 invalid function pointers. Falling back to L3");
|
||||||
if (level1_.Terminate) level1_.Terminate();
|
FallBackToLevel3();
|
||||||
level1_valid_ = false;
|
|
||||||
return level3_.IsKeyboxOrOEMCertValid ? level3_.IsKeyboxOrOEMCertValid()
|
return level3_.IsKeyboxOrOEMCertValid ? level3_.IsKeyboxOrOEMCertValid()
|
||||||
: OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
: OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
@@ -1205,14 +1228,16 @@ class Adapter {
|
|||||||
wvcdm::metrics::
|
wvcdm::metrics::
|
||||||
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INSTALL_KEYBOX);
|
OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INSTALL_KEYBOX);
|
||||||
}
|
}
|
||||||
if (level1_.Terminate) level1_.Terminate();
|
FallBackToLevel3();
|
||||||
level1_valid_ = false;
|
|
||||||
return level3_.IsKeyboxOrOEMCertValid ? level3_.IsKeyboxOrOEMCertValid()
|
return level3_.IsKeyboxOrOEMCertValid ? level3_.IsKeyboxOrOEMCertValid()
|
||||||
: OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
: OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool level1_valid_;
|
bool level1_valid_;
|
||||||
|
bool level1_initialized_;
|
||||||
|
// If the level 1 fails to initialize once, we don't try again.
|
||||||
|
bool level1_failed_;
|
||||||
void* level1_library_;
|
void* level1_library_;
|
||||||
struct FunctionPointers level1_;
|
struct FunctionPointers level1_;
|
||||||
struct FunctionPointers level3_;
|
struct FunctionPointers level3_;
|
||||||
|
|||||||
Reference in New Issue
Block a user