| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #define XOPEN_SOURCE 500 | 5 #define XOPEN_SOURCE 500 |
| 6 #include <algorithm> | 6 #include <algorithm> |
| 7 #include <elf.h> | 7 #include <elf.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 char* Library::__kernel_vsyscall; | 81 char* Library::__kernel_vsyscall; |
| 82 char* Library::__kernel_sigreturn; | 82 char* Library::__kernel_sigreturn; |
| 83 char* Library::__kernel_rt_sigreturn; | 83 char* Library::__kernel_rt_sigreturn; |
| 84 | 84 |
| 85 Library::~Library() { | 85 Library::~Library() { |
| 86 if (image_size_) { | 86 if (image_size_) { |
| 87 // We no longer need access to a full mapping of the underlying library | 87 // We no longer need access to a full mapping of the underlying library |
| 88 // file. Move the temporarily extended mapping back to where we originally | 88 // file. Move the temporarily extended mapping back to where we originally |
| 89 // found. Make sure to preserve any changes that we might have made since. | 89 // found. Make sure to preserve any changes that we might have made since. |
| 90 Sandbox::SysCalls sys; | 90 Sandbox::SysCalls sys; |
| 91 sys.mprotect(image_, 4096, PROT_READ | PROT_WRITE); | 91 sys.mprotect(image_, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); |
| 92 if (memcmp(image_, memory_ranges_.rbegin()->second.start, 4096)) { | 92 if (memcmp(image_, memory_ranges_.rbegin()->second.start, 4096)) { |
| 93 // Only copy data, if we made any changes in this data. Otherwise there | 93 // Only copy data, if we made any changes in this data. Otherwise there |
| 94 // is no need to create another modified COW mapping. | 94 // is no need to create another modified COW mapping. |
| 95 memcpy(image_, memory_ranges_.rbegin()->second.start, 4096); | 95 memcpy(image_, memory_ranges_.rbegin()->second.start, 4096); |
| 96 } | 96 } |
| 97 sys.mprotect(image_, 4096, PROT_READ | PROT_EXEC); | 97 sys.mprotect(image_, 4096, PROT_READ | PROT_EXEC); |
| 98 sys.mremap(image_, image_size_, 4096, MREMAP_MAYMOVE | MREMAP_FIXED, | 98 sys.mremap(image_, image_size_, 4096, MREMAP_MAYMOVE | MREMAP_FIXED, |
| 99 memory_ranges_.rbegin()->second.start); | 99 memory_ranges_.rbegin()->second.start); |
| 100 } | 100 } |
| 101 } | 101 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 MREMAP_MAYMOVE)); | 235 MREMAP_MAYMOVE)); |
| 236 if (image_size_ == 8192 && image_ == start) { | 236 if (image_size_ == 8192 && image_ == start) { |
| 237 // We really mean it, when we say we want the memory to be moved. | 237 // We really mean it, when we say we want the memory to be moved. |
| 238 image_ = reinterpret_cast<char *>(sys.mremap(start, 4096, image_size_, | 238 image_ = reinterpret_cast<char *>(sys.mremap(start, 4096, image_size_, |
| 239 MREMAP_MAYMOVE)); | 239 MREMAP_MAYMOVE)); |
| 240 sys.munmap(reinterpret_cast<char *>(start) + 4096, 4096); | 240 sys.munmap(reinterpret_cast<char *>(start) + 4096, 4096); |
| 241 } | 241 } |
| 242 if (image_ == MAP_FAILED) { | 242 if (image_ == MAP_FAILED) { |
| 243 image_ = NULL; | 243 image_ = NULL; |
| 244 } else { | 244 } else { |
| 245 sys.MMAP(start, 4096, PROT_READ | PROT_WRITE, | 245 sys.MMAP(start, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, |
| 246 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); | 246 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); |
| 247 for (int i = 4096 / sizeof(long); --i; | 247 for (int i = 4096 / sizeof(long); --i; |
| 248 reinterpret_cast<long *>(start)[i] = | 248 reinterpret_cast<long *>(start)[i] = |
| 249 reinterpret_cast<long *>(image_)[i]); | 249 reinterpret_cast<long *>(image_)[i]); |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 if (image_) { | 253 if (image_) { |
| 254 if (offset + len > image_size_) { | 254 if (offset + len > image_size_) { |
| 255 // It is quite likely that we initially did not map the entire file as | 255 // It is quite likely that we initially did not map the entire file as |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 #if defined(__x86_64__) | 868 #if defined(__x86_64__) |
| 869 // VSyscalls live in a shared 4kB page at the top of the address space. This | 869 // VSyscalls live in a shared 4kB page at the top of the address space. This |
| 870 // page cannot be unmapped nor remapped. We have to create a copy within | 870 // page cannot be unmapped nor remapped. We have to create a copy within |
| 871 // 2GB of the page, and rewrite all IP-relative accesses to shared variables. | 871 // 2GB of the page, and rewrite all IP-relative accesses to shared variables. |
| 872 // As the top of the address space is not accessible by mmap(), this means | 872 // As the top of the address space is not accessible by mmap(), this means |
| 873 // that we need to wrap around addresses to the bottom 2GB of the address | 873 // that we need to wrap around addresses to the bottom 2GB of the address |
| 874 // space. | 874 // space. |
| 875 // Only x86-64 has VSyscalls. | 875 // Only x86-64 has VSyscalls. |
| 876 if (maps_->vsyscall()) { | 876 if (maps_->vsyscall()) { |
| 877 char* copy = maps_->allocNearAddr(maps_->vsyscall(), 0x1000, | 877 char* copy = maps_->allocNearAddr(maps_->vsyscall(), 0x1000, |
| 878 PROT_READ|PROT_WRITE); | 878 PROT_READ|PROT_WRITE|PROT_EXEC); |
| 879 char* extraSpace = copy; | 879 char* extraSpace = copy; |
| 880 int extraLength = 0x1000; | 880 int extraLength = 0x1000; |
| 881 memcpy(copy, maps_->vsyscall(), 0x1000); | 881 memcpy(copy, maps_->vsyscall(), 0x1000); |
| 882 long adjust = (long)maps_->vsyscall() - (long)copy; | 882 long adjust = (long)maps_->vsyscall() - (long)copy; |
| 883 for (int vsys = 0; vsys < 0x1000; vsys += 0x400) { | 883 for (int vsys = 0; vsys < 0x1000; vsys += 0x400) { |
| 884 char* start = copy + vsys; | 884 char* start = copy + vsys; |
| 885 char* end = start + 0x400; | 885 char* end = start + 0x400; |
| 886 | 886 |
| 887 // There can only be up to four VSyscalls starting at an offset of | 887 // There can only be up to four VSyscalls starting at an offset of |
| 888 // n*0x1000, each. VSyscalls are invoked by functions in the VDSO | 888 // n*0x1000, each. VSyscalls are invoked by functions in the VDSO |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 } | 1202 } |
| 1203 iter = symbols_.find("__kernel_rt_sigreturn"); | 1203 iter = symbols_.find("__kernel_rt_sigreturn"); |
| 1204 if (iter != symbols_.end() && iter->second.st_value) { | 1204 if (iter != symbols_.end() && iter->second.st_value) { |
| 1205 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; | 1205 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; |
| 1206 } | 1206 } |
| 1207 | 1207 |
| 1208 return true; | 1208 return true; |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 } // namespace | 1211 } // namespace |
| OLD | NEW |