Added more checking upon resolution and bytecode rewriting to verifier.

Access checks are performed when methods and fields are resolved. Also,
erroring bytecodes are now overwritten in the memory mapped dex file.
To do this, the code sets the memory mapped dex file as writable before
verification and set it back to read only after verification is done.
The overwritting occurs only in memory and the original dex file remains
unchanged.

Change-Id: I054394fb57e83d1ac5b6f200ab993d70cd9f55e6
diff --git a/src/dex_file.cc b/src/dex_file.cc
index 7c54018..924953f 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -70,6 +70,10 @@
   }
 }
 
+void DexFile::ChangePermissions(int prot) const {
+  closer_->ChangePermissions(prot);
+}
+
 DexFile::Closer::~Closer() {}
 
 DexFile::MmapCloser::MmapCloser(void* addr, size_t length) : addr_(addr), length_(length) {
@@ -80,9 +84,15 @@
     PLOG(INFO) << "munmap failed";
   }
 }
+void DexFile::MmapCloser::ChangePermissions(int prot) {
+  if (mprotect(addr_, length_, prot) != 0) {
+    PLOG(FATAL) << "Failed to change dex file permissions to " << prot;
+  }
+}
 
 DexFile::PtrCloser::PtrCloser(byte* addr) : addr_(addr) {}
 DexFile::PtrCloser::~PtrCloser() { delete[] addr_; }
+void DexFile::PtrCloser::ChangePermissions(int prot) {}
 
 const DexFile* DexFile::OpenFile(const std::string& filename,
                                  const std::string& original_location,
@@ -106,7 +116,7 @@
     return NULL;
   }
   size_t length = sbuf.st_size;
-  void* addr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
+  void* addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
   if (addr == MAP_FAILED) {
     PLOG(ERROR) << "mmap \"" << filename << "\" failed";
     close(fd);