nsIDOMWindow* PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent) { if (!parent) { return nullptr; } TabParent* tabParent = TabParent::GetFrom(parent); if (!tabParent) { return nullptr; } nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement(); if (!frameElement) { return nullptr; } nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement)); if (!frame) { return nullptr; } nsCOMPtr<nsIDOMWindow> parentWin = do_QueryInterface(frame->OwnerDoc()->GetWindow()); if (!parentWin) { return nullptr; } return parentWin; }
NS_IMETHODIMP HangMonitoredProcess::GetScriptBrowser(nsIDOMElement** aBrowser) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); if (mHangData.type() != HangData::TSlowScriptData) { return NS_ERROR_NOT_AVAILABLE; } TabId tabId = mHangData.get_SlowScriptData().tabId(); if (!mContentParent) { return NS_ERROR_NOT_AVAILABLE; } nsTArray<PBrowserParent*> tabs; mContentParent->ManagedPBrowserParent(tabs); for (size_t i = 0; i < tabs.Length(); i++) { TabParent* tp = TabParent::GetFrom(tabs[i]); if (tp->GetTabId() == tabId) { nsCOMPtr<nsIDOMElement> node = do_QueryInterface(tp->GetOwnerElement()); node.forget(aBrowser); return NS_OK; } } *aBrowser = nullptr; return NS_OK; }
bool ScreenManagerParent::RecvScreenForBrowser(PBrowserParent* aBrowser, ScreenDetails* aRetVal, bool* aSuccess) { *aSuccess = false; // Find the mWidget associated with the tabparent, and then return // the nsIScreen it's on. TabParent* tabParent = static_cast<TabParent*>(aBrowser); nsCOMPtr<nsIWidget> widget = tabParent->GetWidget(); if (!widget) { return true; } nsCOMPtr<nsIScreen> screen; if (widget->GetNativeData(NS_NATIVE_WINDOW)) { mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW), getter_AddRefs(screen)); } NS_ENSURE_TRUE(screen, true); ScreenDetails details; if (!ExtractScreenDetails(screen, details)) { return true; } *aRetVal = details; *aSuccess = true; return true; }
bool RenderFrameParent::Init(nsFrameLoader* aFrameLoader) { if (mInitted || !aFrameLoader) { return false; } mFrameLoader = aFrameLoader; RefPtr<LayerManager> lm = GetFrom(mFrameLoader); mAsyncPanZoomEnabled = lm && lm->AsyncPanZoomEnabled(); TabParent* browser = TabParent::GetFrom(mFrameLoader); if (XRE_IsParentProcess()) { // Our remote frame will push layers updates to the compositor, // and we'll keep an indirect reference to that tree. browser->Manager()->AsContentParent()->AllocateLayerTreeId(browser, &mLayersId); if (lm && lm->AsClientLayerManager()) { lm->AsClientLayerManager()->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId); } } else if (XRE_IsContentProcess()) { ContentChild::GetSingleton()->SendAllocateLayerTreeId(browser->Manager()->ChildID(), browser->GetTabId(), &mLayersId); CompositorBridgeChild::Get()->SendNotifyChildCreated(mLayersId); } mInitted = true; return true; }
PBrowserParent* ContentParent::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserElement, const AppId& aApp) { // We only use this Alloc() method when the content processes asks // us to open a window. In that case, we're expecting to see the // opening PBrowser as its app descriptor, and we can trust the data // associated with that PBrowser since it's fully owned by this // process. if (AppId::TPBrowserParent != aApp.type()) { NS_ERROR("Content process attempting to forge app ID"); return nullptr; } TabParent* opener = static_cast<TabParent*>(aApp.get_PBrowserParent()); // Popup windows of isBrowser frames are isBrowser if the parent // isBrowser. Allocating a !isBrowser frame with same app ID // would allow the content to access data it's not supposed to. if (opener && opener->IsBrowserElement() && !aIsBrowserElement) { NS_ERROR("Content process attempting to escalate data access privileges"); return nullptr; } TabParent* parent = new TabParent(opener ? opener->GetApp() : nullptr, aIsBrowserElement); // We release this ref in DeallocPBrowser() NS_ADDREF(parent); return parent; }
NS_OVERRIDE virtual bool RecvVibrate(const InfallibleTArray<unsigned int>& pattern, const InfallibleTArray<uint64> &id, PBrowserParent *browserParent) { // Check whether browserParent is active. We should have already // checked that the corresponding window is active, but this check // isn't redundant. A window may be inactive in an active // browser. And a window is not notified synchronously when it's // deactivated, so the window may think it's active when the tab // is actually inactive. TabParent *tabParent = static_cast<TabParent*>(browserParent); if (!tabParent->Active()) { HAL_LOG(("RecvVibrate: Tab is not active. Cancelling.")); return true; } // Forward to hal::, not hal_impl::, because we might be a // subprocess of another sandboxed process. The hal:: entry point // will do the right thing. nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(tabParent->GetBrowserDOMWindow()); WindowIdentifier newID(id, window); hal::Vibrate(pattern, newID); return true; }
bool ContentPermissionRequestParent::IsBeingDestroyed() { // When TabParent::Destroy() is called, we are being destroyed. It's unsafe // to send out any message now. TabParent* tabParent = static_cast<TabParent*>(Manager()); return tabParent->IsDestroyed(); }
NS_OVERRIDE virtual bool RecvCancelVibrate(const InfallibleTArray<uint64> &id, PBrowserParent *browserParent) { TabParent *tabParent = static_cast<TabParent*>(browserParent); nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(tabParent->GetBrowserDOMWindow()); WindowIdentifier newID(id, window); hal::CancelVibrate(newID); return true; }
uint32_t TCPServerSocketParent::GetAppId() { uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID; const PContentParent *content = Manager()->Manager(); const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = static_cast<TabParent*>(browsers[0]); appId = tab->OwnAppId(); } return appId; };
virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid) { if (MessageLoop::current() != mUILoop) { mUILoop->PostTask( FROM_HERE, NewRunnableMethod(this, &RemoteContentController::NotifyTransformEnd, aGuid)); return; } if (mRenderFrame) { TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager()); browser->NotifyTransformEnd(aGuid.mScrollId); } }
bool AssertAppStatus(PBrowserParent* aActor, unsigned short aStatus) { if (!aActor) { NS_WARNING("Testing process capability for null actor"); return false; } TabParent* tab = TabParent::GetFrom(aActor); nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp(); return CheckAppStatusHelper(app, aStatus); }
bool AssertAppProcess(PBrowserParent* aActor, AssertAppProcessType aType, const char* aCapability) { if (!aActor) { NS_WARNING("Testing process capability for null actor"); return false; } TabParent* tab = TabParent::GetFrom(aActor); nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp(); return CheckAppTypeHelper(app, aType, aCapability, tab->IsBrowserElement()); }
virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg) { if (MessageLoop::current() != mUILoop) { mUILoop->PostTask( FROM_HERE, NewRunnableMethod(this, &RemoteContentController::NotifyAPZStateChange, aGuid, aChange, aArg)); return; } if (mRenderFrame) { TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager()); browser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg); } }
bool AssertAppProcess(PBrowserParent* aActor, AssertAppProcessType aType, const char* aCapability) { if (!aActor) { NS_WARNING("Testing process capability for null actor"); return false; } TabParent* tab = static_cast<TabParent*>(aActor); nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp(); bool aValid = false; // isBrowser frames inherit their app descriptor to identify their // data storage, but they don't inherit the capability associated // with that descriptor. if (app && (aType == ASSERT_APP_HAS_PERMISSION || !tab->IsBrowserElement())) { switch (aType) { case ASSERT_APP_HAS_PERMISSION: case ASSERT_APP_PROCESS_PERMISSION: if (!NS_SUCCEEDED(app->HasPermission(aCapability, &aValid))) { aValid = false; } break; case ASSERT_APP_PROCESS_MANIFEST_URL: { nsAutoString manifestURL; if (NS_SUCCEEDED(app->GetManifestURL(manifestURL)) && manifestURL.EqualsASCII(aCapability)) { aValid = true; } break; } default: break; } } if (!aValid) { printf_stderr("Security problem: Content process does not have `%s'. It will be killed.\n", aCapability); ContentParent* process = tab->Manager(); process->KillHard(); } return aValid; }
mozilla::ipc::IPCResult nsIContentParent::RecvPBrowserConstructor(PBrowserParent* actor, const TabId& tabId, const TabId& sameTabGroupAs, const IPCTabContext& context, const uint32_t& chromeFlags, const ContentParentId& cpId, const bool& isForBrowser) { TabParent* parent = TabParent::GetFrom(actor); // When enabling input event prioritization, input events may preempt other // normal priority IPC messages. To prevent the input events preempt // PBrowserConstructor, we use an IPC 'RemoteIsReadyToHandleInputEvents' to // notify parent that TabChild is created. In this case, PBrowser is initiated // from content so that we can set TabParent as ready to handle input events. parent->SetReadyToHandleInputEvents(); return IPC_OK(); }
NS_IMETHODIMP HangMonitoredProcess::IsReportForBrowser(nsIFrameLoader* aFrameLoader, bool* aResult) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); if (!mActor) { *aResult = false; return NS_OK; } TabParent* tp = TabParent::GetFrom(aFrameLoader); if (!tp) { *aResult = false; return NS_OK; } *aResult = mContentParent == tp->Manager(); return NS_OK; }
bool ScreenManagerParent::RecvScreenForBrowser(PBrowserParent* aBrowser, ScreenDetails* aRetVal, bool* aSuccess) { *aSuccess = false; #ifdef MOZ_VALGRIND // Zero this so that Valgrind doesn't complain when we send it to another // process. memset(aRetVal, 0, sizeof(ScreenDetails)); #endif // Find the mWidget associated with the tabparent, and then return // the nsIScreen it's on. TabParent* tabParent = static_cast<TabParent*>(aBrowser); nsCOMPtr<nsIWidget> widget = tabParent->GetWidget(); nsCOMPtr<nsIScreen> screen; if (widget) { if (widget->GetNativeData(NS_NATIVE_WINDOW)) { mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW), getter_AddRefs(screen)); } } else { nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen)); if (NS_WARN_IF(NS_FAILED(rv))) { return true; } } NS_ENSURE_TRUE(screen, true); ScreenDetails details; if (!ExtractScreenDetails(screen, details)) { return true; } *aRetVal = details; *aSuccess = true; return true; }
bool AssertAppStatus(PBrowserParent* aActor, unsigned short aStatus) { if (!aActor) { NS_WARNING("Testing process capability for null actor"); return false; } TabParent* tab = static_cast<TabParent*>(aActor); nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp(); if (app) { unsigned short appStatus = 0; if (NS_SUCCEEDED(app->GetAppStatus(&appStatus))) { return appStatus == aStatus; } } return false; }
bool nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext) { const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext(); // We don't trust the IPCTabContext we receive from the child, so we'll bail // if we receive an IPCTabContext that's not a PopupIPCTabContext. // (PopupIPCTabContext lets the child process prove that it has access to // the app it's trying to open.) if (appBrowser.type() != IPCTabAppBrowserContext::TPopupIPCTabContext) { NS_ERROR("Unexpected IPCTabContext type. Aborting AllocPBrowserParent."); return false; } const PopupIPCTabContext& popupContext = appBrowser.get_PopupIPCTabContext(); TabParent* opener = static_cast<TabParent*>(popupContext.openerParent()); if (!opener) { NS_ERROR("Got null opener from child; aborting AllocPBrowserParent."); return false; } // Popup windows of isBrowser frames must be isBrowser if the parent // isBrowser. Allocating a !isBrowser frame with same app ID would allow // the content to access data it's not supposed to. if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) { NS_ERROR("Child trying to escalate privileges! Aborting AllocPBrowserParent."); return false; } MaybeInvalidTabContext tc(aContext); if (!tc.IsValid()) { NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) " "Aborting AllocPBrowserParent.", tc.GetInvalidReason()).get()); return false; } return true; }
bool TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL, const nsString& aBinaryType) { // We don't have browser actors in xpcshell, and hence can't run automated // tests without this loophole. if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } // Obtain App ID uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; const PContentParent *content = Manager()->Manager(); const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = static_cast<TabParent*>(browsers[0]); appId = tab->OwnAppId(); } nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, appId, getter_AddRefs(mSocket)); if (NS_FAILED(rv) || !mSocket) { FireInteralError(this, __LINE__); return true; } return true; }
bool TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost, const uint16_t& aRemotePort, const nsCString& aLocalAddr, const uint16_t& aLocalPort, const bool& aUseSSL, const bool& aUseArrayBuffers, const nsCString& aFilter) { if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } nsresult rv; nsCOMPtr<nsISocketTransportService> sts = do_GetService("@mozilla.org/network/socket-transport-service;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } nsCOMPtr<nsISocketTransport> socketTransport; rv = sts->CreateTransport(nullptr, 0, aRemoteHost, aRemotePort, nullptr, getter_AddRefs(socketTransport)); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } PRNetAddr prAddr; if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) { FireInteralError(this, __LINE__); return true; } if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) { FireInteralError(this, __LINE__); return true; } mozilla::net::NetAddr addr; PRNetAddrToNetAddr(&prAddr, &addr); rv = socketTransport->Bind(&addr); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } if (!aFilter.IsEmpty()) { nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX); contractId.Append(aFilter); nsCOMPtr<nsISocketFilterHandler> filterHandler = do_GetService(contractId.get()); if (!filterHandler) { NS_ERROR("Content doesn't have a valid filter"); FireInteralError(this, __LINE__); return true; } rv = filterHandler->NewFilter(getter_AddRefs(mFilter)); if (NS_FAILED(rv)) { NS_ERROR("Cannot create filter that content specified"); FireInteralError(this, __LINE__); return true; } } // Obtain App ID uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; bool inIsolatedMozBrowser = false; const PContentParent *content = Manager()->Manager(); if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) { // appId's are for B2G only currently, where managees.Count() == 1 // This is not guaranteed currently in Desktop, so skip this there. TabParent *tab = TabParent::GetFrom(browser); appId = tab->OwnAppId(); inIsolatedMozBrowser = tab->IsIsolatedMozBrowserElement(); } mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers); mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser); mSocket->SetSocketBridgeParent(this); rv = mSocket->InitWithUnconnectedTransport(socketTransport); NS_ENSURE_SUCCESS(rv, true); return true; }