Bug 1315543 - Eliminate UAF in Navigator::NotifyVRDisplaysUpdated,r=dmu

This commit is contained in:
Kearwood (Kip) Gilbert 2016-11-24 11:50:43 -08:00
Родитель 934d575f3f
Коммит 53f4153710
5 изменённых файлов: 20 добавлений и 11 удалений

Просмотреть файл

@ -1647,9 +1647,9 @@ Navigator::GetVRDisplays(ErrorResult& aRv)
return nullptr; return nullptr;
} }
// We pass ourself to RefreshVRDisplays, so NotifyVRDisplaysUpdated will // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
// be called asynchronously, resolving the promises in mVRGetDisplaysPromises. // be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
if (!VRDisplay::RefreshVRDisplays(this)) { if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
p->MaybeReject(NS_ERROR_FAILURE); p->MaybeReject(NS_ERROR_FAILURE);
return p.forget(); return p.forget();
} }

Просмотреть файл

@ -77,10 +77,10 @@ VRDisplayCapabilities::MaxLayers() const
} }
/*static*/ bool /*static*/ bool
VRDisplay::RefreshVRDisplays(dom::Navigator* aNavigator) VRDisplay::RefreshVRDisplays(uint64_t aWindowId)
{ {
gfx::VRManagerChild* vm = gfx::VRManagerChild::Get(); gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
return vm && vm->RefreshVRDisplaysWithCallback(aNavigator); return vm && vm->RefreshVRDisplaysWithCallback(aWindowId);
} }
/*static*/ void /*static*/ void

Просмотреть файл

@ -282,7 +282,7 @@ public:
uint32_t DisplayId() const { return mDisplayId; } uint32_t DisplayId() const { return mDisplayId; }
void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; } void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; }
static bool RefreshVRDisplays(dom::Navigator* aNavigator); static bool RefreshVRDisplays(uint64_t aWindowId);
static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays, static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
nsPIDOMWindowInner* aWindow); nsPIDOMWindowInner* aWindow);

Просмотреть файл

@ -269,13 +269,22 @@ mozilla::ipc::IPCResult
VRManagerChild::RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates) VRManagerChild::RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates)
{ {
UpdateDisplayInfo(aDisplayUpdates); UpdateDisplayInfo(aDisplayUpdates);
for (auto& nav : mNavigatorCallbacks) { for (auto& windowId : mNavigatorCallbacks) {
/** We must call NotifyVRDisplaysUpdated for every /** We must call NotifyVRDisplaysUpdated for every
* Navigator in mNavigatorCallbacks to ensure that * window's Navigator in mNavigatorCallbacks to ensure that
* the promise returned by Navigator.GetVRDevices * the promise returned by Navigator.GetVRDevices
* can resolve. This must happen even if no changes * can resolve. This must happen even if no changes
* to VRDisplays have been detected here. * to VRDisplays have been detected here.
*/ */
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(windowId);
if (!window) {
continue;
}
ErrorResult result;
dom::Navigator* nav = window->GetNavigator(result);
if (NS_WARN_IF(result.Failed())) {
continue;
}
nav->NotifyVRDisplaysUpdated(); nav->NotifyVRDisplaysUpdated();
} }
mNavigatorCallbacks.Clear(); mNavigatorCallbacks.Clear();
@ -300,11 +309,11 @@ VRManagerChild::GetVRDisplays(nsTArray<RefPtr<VRDisplayClient>>& aDisplays)
} }
bool bool
VRManagerChild::RefreshVRDisplaysWithCallback(dom::Navigator* aNavigator) VRManagerChild::RefreshVRDisplaysWithCallback(uint64_t aWindowId)
{ {
bool success = SendRefreshDisplays(); bool success = SendRefreshDisplays();
if (success) { if (success) {
mNavigatorCallbacks.AppendElement(aNavigator); mNavigatorCallbacks.AppendElement(aWindowId);
} }
return success; return success;
} }

Просмотреть файл

@ -49,7 +49,7 @@ public:
int GetInputFrameID(); int GetInputFrameID();
bool GetVRDisplays(nsTArray<RefPtr<VRDisplayClient> >& aDisplays); bool GetVRDisplays(nsTArray<RefPtr<VRDisplayClient> >& aDisplays);
bool RefreshVRDisplaysWithCallback(dom::Navigator* aNavigator); bool RefreshVRDisplaysWithCallback(uint64_t aWindowId);
static void InitSameProcess(); static void InitSameProcess();
static void InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint); static void InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint);
@ -152,7 +152,7 @@ private:
nsTArray<RefPtr<VRDisplayClient> > mDisplays; nsTArray<RefPtr<VRDisplayClient> > mDisplays;
bool mDisplaysInitialized; bool mDisplaysInitialized;
nsTArray<dom::Navigator*> mNavigatorCallbacks; nsTArray<uint64_t> mNavigatorCallbacks;
dom::GamepadManager* mGamepadManager; dom::GamepadManager* mGamepadManager;
int32_t mInputFrameID; int32_t mInputFrameID;