Bug 1460989 - Check page protection flags again after mprotect(); r=glandium
authorJim Chen <nchen@mozilla.com>
Wed, 30 May 2018 11:47:07 -0400
changeset 420443 a4465713555bee4fea1ec2c295c7ca51b720903a
parent 420442 ede2ec96fe1ed2b8bf418027bde42bdd23c69505
child 420444 602bdd9d5a96432300e7e8bd69bf608eb16ff952
push id34072
push useraiakab@mozilla.com
push dateWed, 30 May 2018 22:00:19 +0000
treeherdermozilla-central@6272dd5e7417 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1460989
milestone62.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 1460989 - Check page protection flags again after mprotect(); r=glandium We are apparently still crashing even after mprotect() with write flag returns successfully. This patch reads the flags again after mprotect() returns, and hopefully the flags will tell the truth of whether the page is truly writable or not after calling mprotect(). MozReview-Commit-ID: Jsg8vHKFEvJ
mozglue/linker/ElfLoader.cpp
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -906,21 +906,31 @@ public:
 
     if (prot & PROT_WRITE) {
       success = true;
       return;
     }
 
     page = firstPage;
     int ret = mprotect(page, length, prot | PROT_WRITE);
-    success = ret == 0;
+    if (ret != 0) {
+      success = false;
+      WARN("mprotect(%p, %zu, %o) = %d (errno=%d; %s)",
+           page, length, prot | PROT_WRITE, ret, errno, strerror(errno));
+      return;
+    }
+
+    // XXX bug 1460989: on some devices, mprotect appears to return 0 for
+    // success even after _failing_ to make the page writable. Therefore, check
+    // for write access again instead of relying on the mprotect return value.
+    int newProt = getProt(start, &end);
+    success = (newProt != -1) && (newProt & PROT_WRITE);
     if (!success) {
-      ERROR("mprotect(%p, %zu, %d) = %d (errno=%d; %s)",
-            page, length, prot | PROT_WRITE, ret,
-            errno, strerror(errno));
+      WARN("mprotect(%p, %zu, %o) returned 0 but page is not writable: %o",
+           page, length, prot | PROT_WRITE, newProt);
     }
   }
 
   bool IsWritable() const {
     return success;
   }
 
   ~EnsureWritable()