Bug 1427079 - Don't let disposed window be read from parcels; r=snorp
authorJim Chen <nchen@mozilla.com>
Thu, 11 Jan 2018 13:45:54 -0500
changeset 398865 adb5fab118c560f437c9891c98a4c335b635800a
parent 398864 8c3494442dc435a481052dfe1d38101145fe2bf1
child 398866 620b6be0bf0a3716445743555387f2deb07366a7
push id33235
push usernbeleuzu@mozilla.com
push dateFri, 12 Jan 2018 11:16:51 +0000
treeherdermozilla-central@c72e2f43eb63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1427079
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1427079 - Don't let disposed window be read from parcels; r=snorp It's possible for parcels derived from the session to outlast the session lifecycle. This patch makes us return null when trying to retrieve window objects using stale parcels. MozReview-Commit-ID: 3Vp6T3uCEBt
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
widget/android/GeneratedJNIWrappers.h
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
@@ -291,32 +291,46 @@ public class GeckoSession extends LayerS
         private NativeQueue mNativeQueue;
         private Binder mBinder;
 
         public Window(final NativeQueue nativeQueue) {
             mNativeQueue = nativeQueue;
         }
 
         @Override // IInterface
-        public IBinder asBinder() {
+        public Binder asBinder() {
             if (mBinder == null) {
                 mBinder = new Binder();
                 mBinder.attachInterface(this, Window.class.getName());
             }
             return mBinder;
         }
 
         @WrapForJNI(dispatchTo = "proxy")
         public static native void open(Window instance, Compositor compositor,
                                        EventDispatcher dispatcher,
                                        GeckoBundle settings, String chromeUri,
                                        int screenId, boolean privateMode);
 
-        @WrapForJNI(dispatchTo = "proxy")
-        @Override protected native void disposeNative();
+        @Override // JNIObject
+        protected void disposeNative() {
+            // Detach ourselves from the binder as well, to prevent this window from being
+            // read from any parcels.
+            asBinder().attachInterface(null, Window.class.getName());
+
+            if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
+                nativeDisposeNative();
+            } else {
+                GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
+                        this, "nativeDisposeNative");
+            }
+        }
+
+        @WrapForJNI(dispatchTo = "proxy", stubName = "DisposeNative")
+        private native void nativeDisposeNative();
 
         @WrapForJNI(dispatchTo = "proxy")
         public native void close();
 
         @WrapForJNI(dispatchTo = "proxy")
         public native void transfer(Compositor compositor, EventDispatcher dispatcher,
                                     GeckoBundle settings);
 
@@ -523,24 +537,22 @@ public class GeckoSession extends LayerS
         ThreadUtils.assertOnUiThread();
 
         if (!isOpen()) {
             throw new IllegalStateException("Session is not open");
         }
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             mWindow.close();
-            mWindow.disposeNative();
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                     mWindow, "close");
-            GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
-                    mWindow, "disposeNative");
         }
 
+        mWindow.disposeNative();
         mWindow = null;
         onWindowChanged();
     }
 
     private void onWindowChanged() {
         if (mWindow != null) {
             mTextInput.onWindowChanged(mWindow);
         }
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -2287,17 +2287,17 @@ public:
                 mozilla::jni::DispatchTarget::PROXY;
     };
 
     struct DisposeNative_t {
         typedef Window Owner;
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<> Args;
-        static constexpr char name[] = "disposeNative";
+        static constexpr char name[] = "nativeDisposeNative";
         static constexpr char signature[] =
                 "()V";
         static const bool isStatic = false;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =