If we start with this: Compartment 1 | Compartment 2 ------------------------------------------- CCW1 --> XrayWaiver -> WindowProxy Then create a new realm + WindowProxy in compartment 1 and transplant the WindowProxy in compartment 2, we get: Compartment 1 | Compartment 2 ------------------------------------------------- CCW1 --> XrayWaiver -> CCW2(WindowProxy) XrayWaiver WindowProxy In FixWaiverAfterTransplant we then recompute all CCWs for the old XrayWaiver in compartment 2 to point to the new XrayWaiver in compartment 1. However CCW1 and the new XrayWaiver are now same-compartment so we fail an assert in js::RemapWrapper. Initially I thought we could transplant the CCW with a same-compartment wrapper to the same-compartment XrayWaiver, like this: ompartment 1 | Compartment 2 -------------------------------------------------------- Wrapper [unused XrayWaiver] -> CCW2(WindowProxy) -> XrayWaiver -> WindowProxy It works but it breaks the invariant [0] that XrayWaivers are only referenced by CCWs. Another option is to do an UncheckedUnwrap, eliminating the XrayWaiver but this might be wrong if we then again load a content page and transplant the WindowProxy in compartment 1 with a CCW? Then we will end up with a vanilla non-waived Xray I think. [0] https://searchfox.org/mozilla-central/rev/70a4778dd84ec94b4b3a2537fd28482de45b9a00/js/xpconnect/wrappers/WrapperFactory.cpp#624-626
Bug 1516237 Comment 1 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
If we start with this: Compartment 1 | Compartment 2 ------------------------------------------- CCW1 --> XrayWaiver -> WindowProxy Then create a new realm + WindowProxy in compartment 1 and transplant the WindowProxy in compartment 2, we get: Compartment 1 | Compartment 2 ------------------------------------------------- CCW1 --> XrayWaiver -> CCW2(WindowProxy) XrayWaiver WindowProxy In FixWaiverAfterTransplant we then recompute all CCWs for the old XrayWaiver in compartment 2 to point to the new XrayWaiver in compartment 1. However CCW1 and the new XrayWaiver are now same-compartment so we fail an assert in js::RemapWrapper. Initially I thought we could transplant the CCW with a same-compartment wrapper to the same-compartment XrayWaiver, like this: Compartment 1 | Compartment 2 -------------------------------------------------------- Wrapper [unused XrayWaiver] -> CCW2(WindowProxy) -> XrayWaiver -> WindowProxy It works but it breaks the invariant [0] that XrayWaivers are only referenced by CCWs. Another option is to do an UncheckedUnwrap, eliminating the XrayWaiver but this might be wrong if we then again load a content page and transplant the WindowProxy in compartment 1 with a CCW? Then we will end up with a vanilla non-waived Xray I think. [0] https://searchfox.org/mozilla-central/rev/70a4778dd84ec94b4b3a2537fd28482de45b9a00/js/xpconnect/wrappers/WrapperFactory.cpp#624-626