Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1401)

Unified Diff: third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp

Issue 692593002: Fallback library loading when SELinux blocks EXEC permission. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp
index 03589fc944bf654b4db0c5c4768b4c5170b557a8..af9dab28529f63bd3af68da8bd97ea398b6d9ee3 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_elf_loader.cpp
@@ -312,14 +312,58 @@ bool ElfLoader::LoadSegments(Error* error) {
MAP_FIXED | MAP_PRIVATE,
file_page_start + file_offset_);
if (seg_addr == MAP_FAILED) {
- if (errno == EACCES) {
- error->Format("Could not map segment %d: %s. "
- "If you are running L-preview, please upgrade to L.",
- i, strerror(errno));
- } else {
+ int prot_flags = PFLAGS_TO_PROT(phdr->p_flags);
petrcermak 2014/10/29 17:22:12 I would move this line above line 309 and use prot
Anton 2014/10/29 17:47:28 Done.
+ if (errno != EACCES || (prot_flags & PROT_EXEC) != PROT_EXEC) {
+ // We don't have a fallback in this case.
error->Format("Could not map segment %d: %s", i, strerror(errno));
+ return false;
+ }
+
+ // We were unable to map executable code from the file directly.
+ // This can happen because of overly strict SELinux settings prevent
+ // mapping executable code directly. We fallback by copying the
+ // executable code into memory.
+
+ // Add PROT_WRITE to the pages.
+ // Cast away the const (we are making the pages writable).
+ seg_addr = (void*)seg_page_start;
+ if (mprotect(seg_addr, file_length, prot_flags | PROT_WRITE) == -1) {
+ error->Format("mprotect failed to add PROT_WRITE %d: %s",
+ i, strerror(errno));
+ return false;
+ }
+
+ // Map the library for READ.
+ void* lib_addr = fd_.Map((void*)NULL,
+ file_length,
+ PROT_READ,
+ MAP_PRIVATE,
+ file_page_start + file_offset_);
+ if (lib_addr == MAP_FAILED) {
+ error->Format(
+ "Could not map segment (PROT_READ) %d: %s",
+ i, strerror(errno));
+ return false;
+ }
+
+ // Copy the library into the desired location in memory.
+ memcpy(seg_addr, lib_addr, file_length);
+
+ // Unmap the library.
+ if (munmap(lib_addr, file_length) == -1) {
+ error->Format("Failed to unmap the library segment %d: %s",
+ i, strerror(errno));
+ return false;
+ }
+
+ if ((prot_flags & PROT_WRITE) != PROT_WRITE) {
+ // Remove write permissions (PROT_WRITE).
+ if (mprotect(seg_addr, file_length, prot_flags) == -1) {
+ error->Format("mprotect failed to remove PROT_WRITE %d: %s",
+ i, strerror(errno));
+ return false;
+ }
}
- return false;
}
}

Powered by Google App Engine
This is Rietveld 408576698