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 |