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

Side by Side Diff: library.cc

Issue 8596009: Add test for patching a system call instruction (Closed) Base URL: https://seccompsandbox.googlecode.com/svn/trunk
Patch Set: Add comment Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « library.h ('k') | makefile » ('j') | tests/test_patching.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 6
7 #include "library.h" 7 #include "library.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <elf.h> 10 #include <elf.h>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 typedef Elf32_Sxword Elf_Sxword; 52 typedef Elf32_Sxword Elf_Sxword;
53 typedef Elf32_Off Elf_Off; 53 typedef Elf32_Off Elf_Off;
54 typedef Elf32_Section Elf_Section; 54 typedef Elf32_Section Elf_Section;
55 typedef Elf32_Versym Elf_Versym; 55 typedef Elf32_Versym Elf_Versym;
56 #else 56 #else
57 #error Unsupported target platform 57 #error Unsupported target platform
58 #endif 58 #endif
59 59
60 namespace playground { 60 namespace playground {
61 61
62 Maps* Library::maps_;
63 char* Library::__kernel_vsyscall; 62 char* Library::__kernel_vsyscall;
64 char* Library::__kernel_sigreturn; 63 char* Library::__kernel_sigreturn;
65 char* Library::__kernel_rt_sigreturn; 64 char* Library::__kernel_rt_sigreturn;
66 65
67 Library::Library() : 66 Library::Library() :
68 valid_(false), 67 valid_(false),
69 isVDSO_(false), 68 isVDSO_(false),
70 asr_offset_(0), 69 asr_offset_(0),
71 vsys_offset_(0), 70 vsys_offset_(0),
72 image_(0), 71 image_(0),
73 image_size_(0) { 72 image_size_(0),
73 maps_(NULL) {
74 } 74 }
75 75
76 Library::~Library() { 76 Library::~Library() {
77 if (image_size_) { 77 if (image_size_) {
78 // We no longer need access to a full mapping of the underlying library 78 // We no longer need access to a full mapping of the underlying library
79 // file. Move the temporarily extended mapping back to where we originally 79 // file. Move the temporarily extended mapping back to where we originally
80 // found. Make sure to preserve any changes that we might have made since. 80 // found. Make sure to preserve any changes that we might have made since.
81 Sandbox::SysCalls sys; 81 Sandbox::SysCalls sys;
82 sys.mprotect(image_, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); 82 sys.mprotect(image_, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
83 if (memcmp(image_, memory_ranges_.rbegin()->second.start, 4096)) { 83 if (memcmp(image_, memory_ranges_.rbegin()->second.start, 4096)) {
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 return; 1007 return;
1008 #endif 1008 #endif
1009 } 1009 }
1010 SectionTable::const_iterator iter; 1010 SectionTable::const_iterator iter;
1011 if ((iter = section_table_.find(".text")) == section_table_.end()) { 1011 if ((iter = section_table_.find(".text")) == section_table_.end()) {
1012 return; 1012 return;
1013 } 1013 }
1014 const Elf_Shdr& shdr = iter->second.second; 1014 const Elf_Shdr& shdr = iter->second.second;
1015 char* start = reinterpret_cast<char *>(shdr.sh_addr + asr_offset_); 1015 char* start = reinterpret_cast<char *>(shdr.sh_addr + asr_offset_);
1016 char* stop = start + shdr.sh_size; 1016 char* stop = start + shdr.sh_size;
1017 patchSystemCallsInRange(start, stop, &extraSpace, &extraLength);
1018
1019 // Mark our scratch space as write-protected and executable.
1020 if (extraSpace) {
1021 Sandbox::SysCalls sys;
1022 sys.mprotect(extraSpace, 4096, PROT_READ|PROT_EXEC);
1023 }
1024 }
1025
1026 void Library::patchSystemCallsInRange(char* start, char* stop,
1027 char** extraSpace, int* extraLength) {
1017 char* func = start; 1028 char* func = start;
1018 int nopcount = 0; 1029 int nopcount = 0;
1019 bool has_syscall = false; 1030 bool has_syscall = false;
1020 for (char *ptr = start; ptr < stop; ptr++) { 1031 for (char *ptr = start; ptr < stop; ptr++) {
1021 #if defined(__x86_64__) 1032 #if defined(__x86_64__)
1022 if ((*ptr == '\x0F' && ptr[1] == '\x05' /* SYSCALL */) || 1033 if ((*ptr == '\x0F' && ptr[1] == '\x05' /* SYSCALL */) ||
1023 (isVDSO_ && *ptr == '\xFF')) { 1034 (isVDSO_ && *ptr == '\xFF')) {
1024 #elif defined(__i386__) 1035 #elif defined(__i386__)
1025 if ((*ptr == '\xCD' && ptr[1] == '\x80' /* INT $0x80 */) || 1036 if ((*ptr == '\xCD' && ptr[1] == '\x80' /* INT $0x80 */) ||
1026 (*ptr == '\x65' && ptr[1] == '\xFF' && 1037 (*ptr == '\x65' && ptr[1] == '\xFF' &&
(...skipping 13 matching lines...) Expand all
1040 // padded out with NOPs. 1051 // padded out with NOPs.
1041 // 1052 //
1042 // For performance reasons, we quickly scan the entire text segment 1053 // For performance reasons, we quickly scan the entire text segment
1043 // for potential SYSCALLs, and then patch the code in increments of 1054 // for potential SYSCALLs, and then patch the code in increments of
1044 // individual functions. 1055 // individual functions.
1045 if (has_syscall) { 1056 if (has_syscall) {
1046 has_syscall = false; 1057 has_syscall = false;
1047 // Our quick scan of the function found a potential system call. 1058 // Our quick scan of the function found a potential system call.
1048 // Do a more thorough scan, now. 1059 // Do a more thorough scan, now.
1049 patchSystemCallsInFunction(maps_, isVDSO_ ? vsys_offset_ : 0, func, 1060 patchSystemCallsInFunction(maps_, isVDSO_ ? vsys_offset_ : 0, func,
1050 ptr, &extraSpace, &extraLength); 1061 ptr, extraSpace, extraLength);
1051 } 1062 }
1052 func = ptr; 1063 func = ptr;
1053 } 1064 }
1054 nopcount = 0; 1065 nopcount = 0;
1055 } else { 1066 } else {
1056 nopcount = 0; 1067 nopcount = 0;
1057 } 1068 }
1058 } 1069 }
1059 if (has_syscall) { 1070 if (has_syscall) {
1060 // Patch any remaining system calls that were in the last function before 1071 // Patch any remaining system calls that were in the last function before
1061 // the loop terminated. 1072 // the loop terminated.
1062 patchSystemCallsInFunction(maps_, isVDSO_ ? vsys_offset_ : 0, func, stop, 1073 patchSystemCallsInFunction(maps_, isVDSO_ ? vsys_offset_ : 0, func, stop,
1063 &extraSpace, &extraLength); 1074 extraSpace, extraLength);
1064 }
1065
1066 // Mark our scratch space as write-protected and executable.
1067 if (extraSpace) {
1068 Sandbox::SysCalls sys;
1069 sys.mprotect(extraSpace, 4096, PROT_READ|PROT_EXEC);
1070 } 1075 }
1071 } 1076 }
1072 1077
1073 bool Library::parseElf() { 1078 bool Library::parseElf() {
1074 valid_ = true; 1079 valid_ = true;
1075 1080
1076 // Verify ELF header 1081 // Verify ELF header
1077 Elf_Shdr str_shdr; 1082 Elf_Shdr str_shdr;
1078 if (!getOriginal(0, &ehdr_) || 1083 if (!getOriginal(0, &ehdr_) ||
1079 ehdr_.e_ehsize < sizeof(Elf_Ehdr) || 1084 ehdr_.e_ehsize < sizeof(Elf_Ehdr) ||
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 } 1187 }
1183 iter = symbols_.find("__kernel_rt_sigreturn"); 1188 iter = symbols_.find("__kernel_rt_sigreturn");
1184 if (iter != symbols_.end() && iter->second.st_value) { 1189 if (iter != symbols_.end() && iter->second.st_value) {
1185 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value; 1190 __kernel_rt_sigreturn = asr_offset_ + iter->second.st_value;
1186 } 1191 }
1187 1192
1188 return true; 1193 return true;
1189 } 1194 }
1190 1195
1191 } // namespace 1196 } // namespace
OLDNEW
« no previous file with comments | « library.h ('k') | makefile » ('j') | tests/test_patching.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698