From 7cb52c1ccf8a6d29ed2e5216bfccc17fe45f6ac4 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 1 Mar 2021 08:53:15 -0800 Subject: [PATCH] wvcdm: filter logs by app uid This commit is a combination of the following: * http://go/wvgerrit/117003 * http://go/wvgerrit/118303 Bug: 162255728 Test: MediaDrmTest#testGetLogMessages Change-Id: I5699b64d5c4bab463e5b587595fa7d324dc1d93f --- libwvdrmengine/Android.bp | 2 ++ libwvdrmengine/cdm/core/include/cdm_engine.h | 4 +++ .../core/src/oemcrypto_adapter_dynamic.cpp | 3 +++ libwvdrmengine/cdm/include/cdm_identifier.h | 15 ++++++++--- .../include/wv_content_decryption_module.h | 3 +++ .../cdm/src/wv_content_decryption_module.cpp | 13 ++++++++++ libwvdrmengine/cdm/test/integration-test.mk | 1 + libwvdrmengine/cdm/test/unit-test.mk | 1 + libwvdrmengine/cdm/util/include/log.h | 21 ++++++++++++++++ libwvdrmengine/cdm/util/src/log.cpp | 25 ++++++++++++++++++- libwvdrmengine/include_hidl/TypeConvert.h | 21 +++++++++------- .../mediacrypto/include_hidl/WVCryptoPlugin.h | 8 +++++- .../mediacrypto/src_hidl/WVCryptoPlugin.cpp | 12 ++++++++- libwvdrmengine/mediacrypto/test/Android.mk | 1 + .../mediadrm/include_hidl/WVDrmPlugin.h | 7 ++++++ .../mediadrm/src_hidl/WVDrmPlugin.cpp | 3 +++ libwvdrmengine/mediadrm/test/Android.mk | 1 + libwvdrmengine/oemcrypto/test/common.mk | 1 + libwvdrmengine/vts/vendor_module/Android.bp | 1 + 19 files changed, 127 insertions(+), 16 deletions(-) diff --git a/libwvdrmengine/Android.bp b/libwvdrmengine/Android.bp index 7fa785ea..1b40061d 100644 --- a/libwvdrmengine/Android.bp +++ b/libwvdrmengine/Android.bp @@ -241,6 +241,7 @@ cc_library_static { shared_libs: [ "liblog", "libcrypto", + "libhidlbase", ], cflags: ["-DCORE_UTIL_IMPLEMENTATION"], @@ -291,6 +292,7 @@ cc_library_shared { "libbase", "libcrypto", "libdl", + "libhidlbase", "liblog", "libprotobuf-cpp-lite", "libstagefright_foundation", diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index dbedeca3..734cad36 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -351,6 +351,9 @@ class CdmEngine { virtual CdmResponseType SetPlaybackId(const CdmSessionId& session_id, const std::string& playback_id); + virtual void SetUserId(uint32_t user_id) { user_id_ = user_id; } + virtual uint32_t GetUserId() const { return user_id_; } + protected: friend class CdmEngineFactory; @@ -394,6 +397,7 @@ class CdmEngine { FileSystem* file_system_; Clock clock_; std::string spoid_; + uint32_t user_id_; // Usage related variables // Used to isolate a single active usage information license. Loading, diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 068292a3..e3633a2c 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -435,6 +435,7 @@ class WatchDog { status_ = OEMCrypto_SUCCESS; gave_up_ = false; sandbox_id_ = sandbox_id; + uid_ = wvcdm::GetIpcCallingUid(); } // Deleted by either thread. @@ -449,6 +450,7 @@ class WatchDog { // Function called by new worker thread. static void RunWatchDog(void* watcher) { WatchDog* dog = reinterpret_cast(watcher); + wvcdm::SetLoggingUid(dog->uid_); dog->DoInit(); dog->SignalDoneAndCleanUp(); } @@ -610,6 +612,7 @@ class WatchDog { bool running_; bool gave_up_; std::vector sandbox_id_; + uint32_t uid_; }; struct LevelSession { diff --git a/libwvdrmengine/cdm/include/cdm_identifier.h b/libwvdrmengine/cdm/include/cdm_identifier.h index c05d4483..85f3607f 100644 --- a/libwvdrmengine/cdm/include/cdm_identifier.h +++ b/libwvdrmengine/cdm/include/cdm_identifier.h @@ -11,6 +11,7 @@ #include +#include "log.h" #include "wv_cdm_constants.h" namespace wvcdm { @@ -38,6 +39,10 @@ struct CdmIdentifier { // with a CdmEngine instance. This is a simple way to implement that. uint32_t unique_id; + // Operating system user id of the application. Used to filter log messages. + // Defaults to UNKNOWN_UID. + uint32_t user_id; + // This method is needed to check to see if the identifier is equivalent // to the default cdm. E.g. no spoid, origin or app package name. Use this // comparison in lieu of the == operator when checking to see if the @@ -52,7 +57,7 @@ struct CdmIdentifier { inline bool operator==(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { return lhs.spoid == rhs.spoid && lhs.origin == rhs.origin && lhs.app_package_name == rhs.app_package_name && - lhs.unique_id == rhs.unique_id; + lhs.unique_id == rhs.unique_id && lhs.user_id == rhs.user_id; } inline bool operator!=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { @@ -66,7 +71,9 @@ inline bool operator<(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { (lhs.origin == rhs.origin && (lhs.app_package_name < rhs.app_package_name || (lhs.app_package_name == rhs.app_package_name && - lhs.unique_id < rhs.unique_id))))); + (lhs.unique_id < rhs.unique_id || + (lhs.unique_id == rhs.unique_id && + lhs.user_id < rhs.user_id))))))); } inline bool operator>(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { @@ -82,8 +89,8 @@ inline bool operator>=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { } // Provide default -static const CdmIdentifier kDefaultCdmIdentifier = {EMPTY_SPOID, EMPTY_ORIGIN, - EMPTY_APP_PACKAGE_NAME, 0}; +static const CdmIdentifier kDefaultCdmIdentifier = { + EMPTY_SPOID, EMPTY_ORIGIN, EMPTY_APP_PACKAGE_NAME, 0, UNKNOWN_UID}; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 68a14978..b1a9c8c4 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -183,6 +183,9 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { virtual CdmResponseType SetPlaybackId(const CdmSessionId& session_id, const std::string& playback_id); + virtual CdmResponseType GetSessionUserId(const CdmSessionId& session_id, + uint32_t* user_id); + private: struct CdmInfo { CdmInfo(); diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 4033a64c..b6645127 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -442,6 +442,7 @@ CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier( cdms_[identifier].cdm_engine->SetAppPackageName( identifier.app_package_name); cdms_[identifier].cdm_engine->SetSpoid(identifier.spoid); + cdms_[identifier].cdm_engine->SetUserId(identifier.user_id); } cdm_engine = cdms_[identifier].cdm_engine.get(); } @@ -549,9 +550,12 @@ void WvContentDecryptionModule::OnTimerEvent() { { std::unique_lock auto_lock(cdms_lock_); for (auto it = cdms_.begin(); it != cdms_.end(); ++it) { + LoggingUidSetter set_uid(it->first.user_id); it->second.cdm_engine->OnTimerEvent(); } if (cdms_.empty()) { + // The following code cannot be attributed to any app uid. + LoggingUidSetter set_uid(UNKNOWN_UID); if (CryptoSession::TryTerminate()) { // If CryptoSession is in a state to be terminated, try acquiring the // |timer_lock_| before deciding whether to disable the timer. If the @@ -617,4 +621,13 @@ CdmResponseType WvContentDecryptionModule::SetPlaybackId( if (!cdm_engine) return SESSION_NOT_FOUND_23; return cdm_engine->SetPlaybackId(session_id, playback_id); } + +CdmResponseType WvContentDecryptionModule::GetSessionUserId( + const CdmSessionId& session_id, uint32_t* user_id) { + if (!user_id) return PARAMETER_NULL; + CdmEngine* cdm_engine = GetCdmForSessionId(session_id); + if (!cdm_engine) return SESSION_NOT_FOUND_23; + *user_id = cdm_engine->GetUserId(); + return NO_ERROR; +} } // namespace wvcdm diff --git a/libwvdrmengine/cdm/test/integration-test.mk b/libwvdrmengine/cdm/test/integration-test.mk index c3d2bf42..86319d93 100644 --- a/libwvdrmengine/cdm/test/integration-test.mk +++ b/libwvdrmengine/cdm/test/integration-test.mk @@ -55,6 +55,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libcrypto \ libdl \ + libhidlbase \ liblog \ libmedia_omx \ libprotobuf-cpp-lite \ diff --git a/libwvdrmengine/cdm/test/unit-test.mk b/libwvdrmengine/cdm/test/unit-test.mk index 29b8a417..4daa4b88 100644 --- a/libwvdrmengine/cdm/test/unit-test.mk +++ b/libwvdrmengine/cdm/test/unit-test.mk @@ -51,6 +51,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libcrypto \ libdl \ + libhidlbase \ liblog \ libmedia_omx \ libprotobuf-cpp-lite \ diff --git a/libwvdrmengine/cdm/util/include/log.h b/libwvdrmengine/cdm/util/include/log.h index fe7efd8c..28791f35 100644 --- a/libwvdrmengine/cdm/util/include/log.h +++ b/libwvdrmengine/cdm/util/include/log.h @@ -33,6 +33,7 @@ typedef enum { extern LogPriority g_cutoff; struct LogMessage { + uint32_t uid_; int64_t time_ms_; LogPriority priority_; std::string message_; @@ -51,6 +52,26 @@ class LogBuffer { extern LogBuffer g_logbuf; +static const uint32_t UNKNOWN_UID = ~0; + +#ifdef __ANDROID__ +void SetLoggingUid(const uint32_t); +void ClearLoggingUid(); +uint32_t GetLoggingUid(); +uint32_t GetIpcCallingUid(); +#else +static inline void SetLoggingUid(const uint32_t) {} +static inline void ClearLoggingUid() {} +static inline uint32_t GetLoggingUid() { return UNKNOWN_UID; } +static inline uint32_t GetIpcCallingUid() { return UNKNOWN_UID; } +#endif + +struct LoggingUidSetter { + LoggingUidSetter() {} + LoggingUidSetter(uint32_t uid) { SetLoggingUid(uid); } + virtual ~LoggingUidSetter() { ClearLoggingUid(); } +}; + // Enable/disable verbose logging (LOGV). // This function is supplied for cases where the system layer does not // initialize logging. This is also needed to initialize logging in diff --git a/libwvdrmengine/cdm/util/src/log.cpp b/libwvdrmengine/cdm/util/src/log.cpp index c784bb2e..830a4dad 100644 --- a/libwvdrmengine/cdm/util/src/log.cpp +++ b/libwvdrmengine/cdm/util/src/log.cpp @@ -22,6 +22,7 @@ #define LOG_BUF_SIZE 1024 #include "log.h" +#include #include #include @@ -54,6 +55,27 @@ LogPriority g_cutoff = LOG_VERBOSE; LogBuffer g_logbuf; +thread_local bool tl_logging_uid_set_ = false; + +thread_local uint32_t tl_logging_uid_ = UNKNOWN_UID; + +void SetLoggingUid(const uint32_t uid) { + tl_logging_uid_set_ = true; + tl_logging_uid_ = uid; +} + +void ClearLoggingUid() { + tl_logging_uid_set_ = false; + tl_logging_uid_ = UNKNOWN_UID; +} + +uint32_t GetLoggingUid() { return tl_logging_uid_; } + +uint32_t GetIpcCallingUid() { + const auto self = android::hardware::IPCThreadState::selfOrNull(); + return self ? self->getCallingUid() : UNKNOWN_UID; +} + void InitLogging() {} void Log(const char* file, const char* function, int line, LogPriority level, @@ -101,7 +123,8 @@ void Log(const char* file, const char* function, int line, LogPriority level, __android_log_write(prio, LOG_TAG, buf); if (level <= LOG_INFO) { - g_logbuf.addLog({GetCurrentTimeMs(), level, buf}); + uint32_t uid = tl_logging_uid_set_ ? tl_logging_uid_ : GetIpcCallingUid(); + g_logbuf.addLog({uid, GetCurrentTimeMs(), level, buf}); } } diff --git a/libwvdrmengine/include_hidl/TypeConvert.h b/libwvdrmengine/include_hidl/TypeConvert.h index e98447e3..f57b37d9 100644 --- a/libwvdrmengine/include_hidl/TypeConvert.h +++ b/libwvdrmengine/include_hidl/TypeConvert.h @@ -53,16 +53,19 @@ hidl_vec toHidlVec(const std::vector &vec); template<> inline hidl_vec<::drm::V1_4::LogMessage> toHidlVec(const std::vector &vec) { - hidl_vec<::drm::V1_4::LogMessage> hLogs(vec.size()); - for (size_t i = 0; i < vec.size(); i++) { - const auto& msg = vec[i]; - hLogs[i] = { - msg.time_ms_, - toHidlPriority(msg.priority_), - msg.message_, - }; + uint32_t uid = wvcdm::GetIpcCallingUid(); + std::vector<::drm::V1_4::LogMessage> vec2; + for (auto msg : vec) { + if (uid == msg.uid_) { + vec2.push_back({ + msg.time_ms_, + toHidlPriority(msg.priority_), + msg.message_, + }); + } } - return hLogs; + + return hidl_vec<::drm::V1_4::LogMessage>(vec2); } template const hidl_vec toHidlVec(const std::vector &vec) { diff --git a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h index 7847e11e..a4401f82 100644 --- a/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h +++ b/libwvdrmengine/mediacrypto/include_hidl/WVCryptoPlugin.h @@ -10,6 +10,7 @@ #include #include "HidlTypes.h" +#include "log.h" #include "wv_content_decryption_module.h" #include "WVTypes.h" @@ -24,7 +25,7 @@ using ::android::hidl::memory::V1_0::IMemory; struct WVCryptoPlugin : public ::drm::V1_4::ICryptoPlugin { WVCryptoPlugin(const void* data, size_t size, const sp& cdm); - virtual ~WVCryptoPlugin() {} + virtual ~WVCryptoPlugin(); Return requiresSecureDecoderComponent(const hidl_string& mime) override; @@ -67,10 +68,15 @@ struct WVCryptoPlugin : public ::drm::V1_4::ICryptoPlugin { private: WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVCryptoPlugin); + // List this field first so it is destructed last; ensure logging uid + // is cleared right before plugin is destructed. + wvcdm::LoggingUidSetter mLoggingUidSetter; + wvcdm::CdmSessionId mSessionId; std::map > mSharedBufferMap; sp const mCDM; + uint32_t mUserId; Status_V1_2 attemptDecrypt( const wvcdm::CdmDecryptionParametersV16& params, diff --git a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp index 8ec224b8..166b8e8f 100644 --- a/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src_hidl/WVCryptoPlugin.cpp @@ -15,6 +15,7 @@ #include #include "HidlTypes.h" +#include "log.h" #include "mapErrors-inl.h" #include "OEMCryptoCENC.h" #include "openssl/sha.h" @@ -56,12 +57,21 @@ using wvcdm::WvContentDecryptionModule; WVCryptoPlugin::WVCryptoPlugin(const void* data, size_t size, const sp& cdm) - : mCDM(cdm){ + : mCDM(cdm), + mUserId(wvcdm::UNKNOWN_UID) { if (data != NULL) { mSessionId.assign(static_cast(data), size); } if (!mCDM->IsOpenSession(mSessionId)) { mSessionId.clear(); + } else { + mCDM->GetSessionUserId(mSessionId, &mUserId); + } +} + +WVCryptoPlugin::~WVCryptoPlugin() { + if (wvcdm::UNKNOWN_UID != mUserId) { + wvcdm::SetLoggingUid(mUserId); } } diff --git a/libwvdrmengine/mediacrypto/test/Android.mk b/libwvdrmengine/mediacrypto/test/Android.mk index ff7f3961..51666840 100644 --- a/libwvdrmengine/mediacrypto/test/Android.mk +++ b/libwvdrmengine/mediacrypto/test/Android.mk @@ -35,6 +35,7 @@ LOCAL_SHARED_LIBRARIES := \ libcrypto \ libcutils \ libdl \ + libhidlbase \ liblog \ libprotobuf-cpp-lite \ libstagefright_foundation \ diff --git a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h index 62e57d13..fb22e34b 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVDrmPlugin.h @@ -11,6 +11,7 @@ #include "cdm_client_property_set.h" #include "cdm_identifier.h" +#include "log.h" #include "wv_cdm_event_listener.h" #include "wv_content_decryption_module.h" #include "OEMCryptoCENC.h" @@ -264,6 +265,10 @@ struct WVDrmPlugin : public ::drm::V1_4::IDrmPlugin, IDrmPluginListener, private: WVDRM_DISALLOW_COPY_AND_ASSIGN_AND_NEW(WVDrmPlugin); + // List this field first so it is destructed last; ensure logging uid + // is cleared right before plugin is destructed. + wvcdm::LoggingUidSetter mLoggingUidSetter; + struct CryptoSession { public: CryptoSession() @@ -414,6 +419,8 @@ struct WVDrmPlugin : public ::drm::V1_4::IDrmPlugin, IDrmPluginListener, // until a call to getCdmIdentifier. bool is_sealed() { return mIsIdentifierSealed; } + uint32_t user_id() const { return mCdmIdentifier.user_id; } + private: WVDRM_DISALLOW_COPY_AND_ASSIGN(CdmIdentifierBuilder); diff --git a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp index 064e8701..0b2ff24b 100644 --- a/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src_hidl/WVDrmPlugin.cpp @@ -20,6 +20,7 @@ #include "TypeConvert.h" #include "android-base/macros.h" #include "hidl_metrics_adapter.h" +#include "log.h" #include "mapErrors-inl.h" #include "media/stagefright/MediaErrors.h" #include "openssl/sha.h" @@ -198,6 +199,7 @@ WVDrmPlugin::WVDrmPlugin(const sp& cdm, mAppPackageName(appPackageName) {} WVDrmPlugin::~WVDrmPlugin() { + wvcdm::SetLoggingUid(mCdmIdentifierBuilder.user_id()); typedef map::iterator mapIterator; for (mapIterator iter = mCryptoSessions.begin(); iter != mCryptoSessions.end(); @@ -2188,6 +2190,7 @@ WVDrmPlugin::CdmIdentifierBuilder::CdmIdentifierBuilder( mParent(parent) { mCdmIdentifier.app_package_name = mAppPackageName; mCdmIdentifier.unique_id = getNextUniqueId(); + mCdmIdentifier.user_id = wvcdm::GetIpcCallingUid(); } Status WVDrmPlugin::CdmIdentifierBuilder::getCdmIdentifier( diff --git a/libwvdrmengine/mediadrm/test/Android.mk b/libwvdrmengine/mediadrm/test/Android.mk index aad213f3..15cbbb78 100644 --- a/libwvdrmengine/mediadrm/test/Android.mk +++ b/libwvdrmengine/mediadrm/test/Android.mk @@ -35,6 +35,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libcrypto \ libdl \ + libhidlbase \ liblog \ libprotobuf-cpp-lite \ libutils \ diff --git a/libwvdrmengine/oemcrypto/test/common.mk b/libwvdrmengine/oemcrypto/test/common.mk index f531b5c2..daf7c0e4 100644 --- a/libwvdrmengine/oemcrypto/test/common.mk +++ b/libwvdrmengine/oemcrypto/test/common.mk @@ -46,6 +46,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libcrypto \ libdl \ + libhidlbase \ liblog \ libmedia_omx \ libprotobuf-cpp-lite \ diff --git a/libwvdrmengine/vts/vendor_module/Android.bp b/libwvdrmengine/vts/vendor_module/Android.bp index a1b28d4d..498a4135 100644 --- a/libwvdrmengine/vts/vendor_module/Android.bp +++ b/libwvdrmengine/vts/vendor_module/Android.bp @@ -45,6 +45,7 @@ cc_library_shared { shared_libs: [ "libbase", "libcrypto", + "libhidlbase", "liblog", "libssl", "libutils",