diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 89e6226b719ba5..66d9f26b397f25 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc @@ -34,6 +34,14 @@ using media::MediaSourcePlayer; // attempting to release inactive media players. static const int kMediaPlayerThreshold = 1; +// Maximum sizes for various EME message parameters. These are checks to +// prevent unnecessarily large messages from being passed around, and the sizes +// are somewhat arbitrary as the EME specification doesn't specify any limits. +static const size_t kEmeUuidSize = 16; +static const size_t kEmeTypeMaximum = 50; // Type is a MIME type. +static const size_t kEmeInitDataMaximum = 10240; // 10 KB +static const size_t kEmeResponseMaximum = 10240; // 10 KB + namespace content { static BrowserMediaPlayerManager::Factory g_factory = NULL; @@ -123,11 +131,9 @@ bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { DestroyAllMediaPlayers) IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM, OnInitializeCDM) - IPC_MESSAGE_HANDLER(MediaKeysHostMsg_GenerateKeyRequest, - OnGenerateKeyRequest) - IPC_MESSAGE_HANDLER(MediaKeysHostMsg_AddKey, OnAddKey) - IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CancelKeyRequest, - OnCancelKeyRequest) + IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CreateSession, OnCreateSession) + IPC_MESSAGE_HANDLER(MediaKeysHostMsg_UpdateSession, OnUpdateSession) + IPC_MESSAGE_HANDLER(MediaKeysHostMsg_ReleaseSession, OnReleaseSession) #if defined(GOOGLE_TV) IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, OnNotifyExternalSurface) @@ -355,7 +361,7 @@ void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) { // During the process, DisableFullscreenEncryptedMediaPlayback() may get // called before or after OnEnterFullscreen(). If it is called before // OnEnterFullscreen(), the player will not enter fullscreen. And it will - // retry the process once the GenerateKeyRequest is allowed to proceed + // retry the process once CreateSession() is allowed to proceed. // TODO(qinmin): make this flag default on android. if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableGestureRequirementForMediaFullscreen)) { @@ -369,7 +375,7 @@ void BrowserMediaPlayerManager::OnSessionCreated( int media_keys_id, uint32 session_id, const std::string& web_session_id) { - Send(new MediaKeysMsg_SetSessionId( + Send(new MediaKeysMsg_SessionCreated( routing_id(), media_keys_id, session_id, web_session_id)); } @@ -378,18 +384,18 @@ void BrowserMediaPlayerManager::OnSessionMessage( uint32 session_id, const std::vector& message, const std::string& destination_url) { - Send(new MediaKeysMsg_KeyMessage( + Send(new MediaKeysMsg_SessionMessage( routing_id(), media_keys_id, session_id, message, destination_url)); } void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id, uint32 session_id) { - Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, session_id)); + Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id)); } void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id, uint32 session_id) { - // TODO(jrummell): Update Android calls and IPC names. + Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id)); } void BrowserMediaPlayerManager::OnSessionError( @@ -397,7 +403,7 @@ void BrowserMediaPlayerManager::OnSessionError( uint32 session_id, media::MediaKeys::KeyError error_code, int system_code) { - Send(new MediaKeysMsg_KeyError( + Send(new MediaKeysMsg_SessionError( routing_id(), media_keys_id, session_id, error_code, system_code)); } @@ -546,17 +552,35 @@ void BrowserMediaPlayerManager::OnInitializeCDM( int media_keys_id, const std::vector& uuid, const GURL& frame_url) { + if (uuid.size() != kEmeUuidSize) { + // This failure will be discovered and reported by OnCreateSession() + // as GetDrmBridge() will return null. + NOTREACHED() << "Invalid UUID for ID: " << media_keys_id; + return; + } + AddDrmBridge(media_keys_id, uuid, frame_url); // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| // is the same as the |player_id|. OnSetMediaKeys(media_keys_id, media_keys_id); } -void BrowserMediaPlayerManager::OnGenerateKeyRequest( +void BrowserMediaPlayerManager::OnCreateSession( int media_keys_id, uint32 session_id, const std::string& type, const std::vector& init_data) { + if (type.length() > kEmeTypeMaximum) { + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + if (init_data.size() > kEmeInitDataMaximum) { + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + if (CommandLine::ForCurrentProcess() ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { GenerateKeyIfAllowed(media_keys_id, session_id, type, init_data, true); @@ -586,10 +610,10 @@ void BrowserMediaPlayerManager::OnGenerateKeyRequest( init_data)); } -void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, - uint32 session_id, - const std::vector& key, - const std::vector& init_data) { +void BrowserMediaPlayerManager::OnUpdateSession( + int media_keys_id, + uint32 session_id, + const std::vector& response) { MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; @@ -598,8 +622,15 @@ void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, return; } - DCHECK(init_data.empty()); - drm_bridge->UpdateSession(session_id, &key[0], key.size()); + if (response.size() > kEmeResponseMaximum) { + DLOG(WARNING) << "Response for ID: " << media_keys_id + << " too long: " << response.size(); + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + + drm_bridge->UpdateSession(session_id, &response[0], response.size()); // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| // is the same as the |player_id|. // TODO(xhwang): Separate |media_keys_id| and |player_id|. @@ -608,8 +639,8 @@ void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, player->OnKeyAdded(); } -void BrowserMediaPlayerManager::OnCancelKeyRequest(int media_keys_id, - uint32 session_id) { +void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id, + uint32 session_id) { MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; @@ -681,7 +712,7 @@ void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id, scoped_ptr drm_bridge(MediaDrmBridge::Create( media_keys_id, uuid, frame_url, security_level, this)); if (!drm_bridge) { - // This failure will be discovered and reported by OnGenerateKeyRequest() + // This failure will be discovered and reported by OnCreateSession() // as GetDrmBridge() will return null. DVLOG(1) << "failed to create drm bridge."; return; diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index 4f8cf85214ddb2..36ed0618eade5a 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h @@ -135,15 +135,14 @@ class CONTENT_EXPORT BrowserMediaPlayerManager void OnInitializeCDM(int media_keys_id, const std::vector& uuid, const GURL& frame_url); - void OnGenerateKeyRequest(int media_keys_id, - uint32 session_id, - const std::string& type, - const std::vector& init_data); - void OnAddKey(int media_keys_id, - uint32 session_id, - const std::vector& key, - const std::vector& init_data); - void OnCancelKeyRequest(int media_keys_id, uint32 session_id); + void OnCreateSession(int media_keys_id, + uint32 session_id, + const std::string& type, + const std::vector& init_data); + void OnUpdateSession(int media_keys_id, + uint32 session_id, + const std::vector& response); + void OnReleaseSession(int media_keys_id, uint32 session_id); void OnSetMediaKeys(int player_id, int media_keys_id); #if defined(GOOGLE_TV) diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h index 96a45ffcd2b505..24778377ad1c7d 100644 --- a/content/common/media/media_player_messages_android.h +++ b/content/common/media/media_player_messages_android.h @@ -287,39 +287,44 @@ IPC_MESSAGE_ROUTED3(MediaKeysHostMsg_InitializeCDM, std::vector /* uuid */, GURL /* frame url */) -IPC_MESSAGE_ROUTED4(MediaKeysHostMsg_GenerateKeyRequest, +IPC_MESSAGE_ROUTED4(MediaKeysHostMsg_CreateSession, int /* media_keys_id */, uint32_t /* session_id */, std::string /* type */, std::vector /* init_data */) +// TODO(jrummell): Use enum for type (http://crbug.com/327449) -IPC_MESSAGE_ROUTED4(MediaKeysHostMsg_AddKey, +IPC_MESSAGE_ROUTED3(MediaKeysHostMsg_UpdateSession, int /* media_keys_id */, uint32_t /* session_id */, - std::vector /* key */, - std::vector /* init_data */) - -IPC_MESSAGE_ROUTED2(MediaKeysHostMsg_CancelKeyRequest, - int /* media_keys_id */, - uint32_t /* session_id */) + std::vector /* response */) -IPC_MESSAGE_ROUTED2(MediaKeysMsg_KeyAdded, +IPC_MESSAGE_ROUTED2(MediaKeysHostMsg_ReleaseSession, int /* media_keys_id */, uint32_t /* session_id */) -IPC_MESSAGE_ROUTED4(MediaKeysMsg_KeyError, +IPC_MESSAGE_ROUTED3(MediaKeysMsg_SessionCreated, int /* media_keys_id */, uint32_t /* session_id */, - media::MediaKeys::KeyError /* error_code */, - int /* system_code */) + std::string /* web_session_id */) -IPC_MESSAGE_ROUTED4(MediaKeysMsg_KeyMessage, +IPC_MESSAGE_ROUTED4(MediaKeysMsg_SessionMessage, int /* media_keys_id */, uint32_t /* session_id */, std::vector /* message */, std::string /* destination_url */) +// TODO(jrummell): Use GURL for destination_url (http://crbug.com/326663) + +IPC_MESSAGE_ROUTED2(MediaKeysMsg_SessionReady, + int /* media_keys_id */, + uint32_t /* session_id */) + +IPC_MESSAGE_ROUTED2(MediaKeysMsg_SessionClosed, + int /* media_keys_id */, + uint32_t /* session_id */) -IPC_MESSAGE_ROUTED3(MediaKeysMsg_SetSessionId, +IPC_MESSAGE_ROUTED4(MediaKeysMsg_SessionError, int /* media_keys_id */, uint32_t /* session_id */, - std::string /* web_session_id */) + media::MediaKeys::KeyError /* error_code */, + int /* system_code */) diff --git a/content/renderer/media/android/proxy_media_keys.cc b/content/renderer/media/android/proxy_media_keys.cc index ed7991a6c2ef21..ef93a2552fb998 100644 --- a/content/renderer/media/android/proxy_media_keys.cc +++ b/content/renderer/media/android/proxy_media_keys.cc @@ -49,7 +49,7 @@ bool ProxyMediaKeys::CreateSession(uint32 session_id, const std::string& type, const uint8* init_data, int init_data_length) { - manager_->GenerateKeyRequest( + manager_->CreateSession( media_keys_id_, session_id, type, @@ -60,14 +60,14 @@ bool ProxyMediaKeys::CreateSession(uint32 session_id, void ProxyMediaKeys::UpdateSession(uint32 session_id, const uint8* response, int response_length) { - manager_->AddKey(media_keys_id_, - session_id, - std::vector(response, response + response_length), - std::vector()); + manager_->UpdateSession( + media_keys_id_, + session_id, + std::vector(response, response + response_length)); } void ProxyMediaKeys::ReleaseSession(uint32 session_id) { - manager_->CancelKeyRequest(media_keys_id_, session_id); + manager_->ReleaseSession(media_keys_id_, session_id); } void ProxyMediaKeys::OnSessionCreated(uint32 session_id, diff --git a/content/renderer/media/android/renderer_media_player_manager.cc b/content/renderer/media/android/renderer_media_player_manager.cc index f94185f5cad643..4767b17aaadb8b 100644 --- a/content/renderer/media/android/renderer_media_player_manager.cc +++ b/content/renderer/media/android/renderer_media_player_manager.cc @@ -12,6 +12,13 @@ #include "content/renderer/media/android/webmediaplayer_android.h" #include "ui/gfx/rect_f.h" +// Maximum sizes for various EME message parameters. These are checks to +// prevent unnecessarily large messages from being passed around, and the sizes +// are somewhat arbitrary as the EME specification doesn't specify any limits. +static const size_t kEmeWebSessionIdMaximum = 512; +static const size_t kEmeMessageMaximum = 10240; // 10 KB +static const size_t kEmeDestinationUrlMaximum = 2048; // 2 KB + namespace content { RendererMediaPlayerManager::RendererMediaPlayerManager(RenderView* render_view) @@ -57,11 +64,11 @@ bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidExitFullscreen, OnDidExitFullscreen) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPlay, OnPlayerPlay) IPC_MESSAGE_HANDLER(MediaPlayerMsg_DidMediaPlayerPause, OnPlayerPause) - // TODO(jrummell): Update IPC names for EME WD and add Closed. - IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyAdded, OnSessionReady) - IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyError, OnSessionError) - IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyMessage, OnSessionMessage) - IPC_MESSAGE_HANDLER(MediaKeysMsg_SetSessionId, OnSessionCreated) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionCreated, OnSessionCreated) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionMessage, OnSessionMessage) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionReady, OnSessionReady) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionClosed, OnSessionClosed) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SessionError, OnSessionError) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -233,26 +240,26 @@ void RendererMediaPlayerManager::InitializeCDM(int media_keys_id, routing_id(), media_keys_id, uuid, frame_url)); } -void RendererMediaPlayerManager::GenerateKeyRequest( +void RendererMediaPlayerManager::CreateSession( int media_keys_id, uint32 session_id, const std::string& type, const std::vector& init_data) { - Send(new MediaKeysHostMsg_GenerateKeyRequest( + Send(new MediaKeysHostMsg_CreateSession( routing_id(), media_keys_id, session_id, type, init_data)); } -void RendererMediaPlayerManager::AddKey(int media_keys_id, - uint32 session_id, - const std::vector& key, - const std::vector& init_data) { - Send(new MediaKeysHostMsg_AddKey( - routing_id(), media_keys_id, session_id, key, init_data)); +void RendererMediaPlayerManager::UpdateSession( + int media_keys_id, + uint32 session_id, + const std::vector& response) { + Send(new MediaKeysHostMsg_UpdateSession( + routing_id(), media_keys_id, session_id, response)); } -void RendererMediaPlayerManager::CancelKeyRequest(int media_keys_id, - uint32 session_id) { - Send(new MediaKeysHostMsg_CancelKeyRequest( +void RendererMediaPlayerManager::ReleaseSession(int media_keys_id, + uint32 session_id) { + Send(new MediaKeysHostMsg_ReleaseSession( routing_id(), media_keys_id, session_id)); } @@ -260,6 +267,12 @@ void RendererMediaPlayerManager::OnSessionCreated( int media_keys_id, uint32 session_id, const std::string& web_session_id) { + if (web_session_id.length() > kEmeWebSessionIdMaximum) { + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); if (media_keys) media_keys->OnSessionCreated(session_id, web_session_id); @@ -270,6 +283,17 @@ void RendererMediaPlayerManager::OnSessionMessage( uint32 session_id, const std::vector& message, const std::string& destination_url) { + if (message.size() > kEmeMessageMaximum) { + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + if (destination_url.length() > kEmeDestinationUrlMaximum) { + OnSessionError( + media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + return; + } + ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); if (media_keys) media_keys->OnSessionMessage(session_id, message, destination_url); diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h index 50cefad7f9fdd6..0965611660f368 100644 --- a/content/renderer/media/android/renderer_media_player_manager.h +++ b/content/renderer/media/android/renderer_media_player_manager.h @@ -93,15 +93,14 @@ class RendererMediaPlayerManager : public RenderViewObserver { ProxyMediaKeys* media_keys, const std::vector& uuid, const GURL& frame_url); - void GenerateKeyRequest(int media_keys_id, - uint32 session_id, - const std::string& type, - const std::vector& init_data); - void AddKey(int media_keys_id, - uint32 session_id, - const std::vector& key, - const std::vector& init_data); - void CancelKeyRequest(int media_keys_id, uint32 session_id); + void CreateSession(int media_keys_id, + uint32 session_id, + const std::string& type, + const std::vector& init_data); + void UpdateSession(int media_keys_id, + uint32 session_id, + const std::vector& response); + void ReleaseSession(int media_keys_id, uint32 session_id); // Registers and unregisters a WebMediaPlayerAndroid object. int RegisterMediaPlayer(WebMediaPlayerAndroid* player);