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

Side by Side Diff: sandbox/src/crosscall_server.cc

Issue 3135041: Merge 56938 - Sbox IPC fix... (Closed) Base URL: svn://svn.chromium.org/chrome/branches/472/src/
Patch Set: Created 10 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/src/crosscall_params.h ('k') | sandbox/src/ipc_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-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 #include <string> 5 #include <string>
6 #include <vector> 6 #include <vector>
7 7
8 #include "sandbox/src/crosscall_server.h" 8 #include "sandbox/src/crosscall_server.h"
9 #include "sandbox/src/crosscall_params.h" 9 #include "sandbox/src/crosscall_params.h"
10 #include "sandbox/src/crosscall_client.h" 10 #include "sandbox/src/crosscall_client.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 delete[] reinterpret_cast<char*>(raw_memory); 79 delete[] reinterpret_cast<char*>(raw_memory);
80 } 80 }
81 81
82 // This function uses a SEH try block so cannot use C++ objects that 82 // This function uses a SEH try block so cannot use C++ objects that
83 // have destructors or else you get Compiler Error C2712. So no DCHECKs 83 // have destructors or else you get Compiler Error C2712. So no DCHECKs
84 // inside this function. 84 // inside this function.
85 CrossCallParamsEx* CrossCallParamsEx::CreateFromBuffer(void* buffer_base, 85 CrossCallParamsEx* CrossCallParamsEx::CreateFromBuffer(void* buffer_base,
86 size_t buffer_size, 86 size_t buffer_size,
87 size_t* output_size) { 87 size_t* output_size) {
88 // IMPORTANT: Everything inside buffer_base and derived from it such
89 // as param_count and declared_size is untrusted.
88 if (NULL == buffer_base) { 90 if (NULL == buffer_base) {
89 return NULL; 91 return NULL;
90 } 92 }
91 if (buffer_size < sizeof(CrossCallParams)) { 93 if (buffer_size < sizeof(CrossCallParams)) {
92 return NULL; 94 return NULL;
93 } 95 }
94 if (buffer_size > kMaxBufferSize) { 96 if (buffer_size > kMaxBufferSize) {
95 return NULL; 97 return NULL;
96 } 98 }
99
97 char* backing_mem = NULL; 100 char* backing_mem = NULL;
98 size_t param_count = 0; 101 size_t param_count = 0;
102 size_t declared_size;
103 size_t min_declared_size;
99 CrossCallParamsEx* copied_params = NULL; 104 CrossCallParamsEx* copied_params = NULL;
100 size_t actual_size;
101 105
102 // Touching the untrusted buffer is done under a SEH try block. This 106 // Touching the untrusted buffer is done under a SEH try block. This
103 // will catch memory access violations so we don't crash. 107 // will catch memory access violations so we don't crash.
104 __try { 108 __try {
105 CrossCallParams* call_params = 109 CrossCallParams* call_params =
106 reinterpret_cast<CrossCallParams*>(buffer_base); 110 reinterpret_cast<CrossCallParams*>(buffer_base);
107 // Check against the minimum size given the number of stated params 111 // Check against the minimum size given the number of stated params
108 // if too small we bail out. 112 // if too small we bail out.
109 param_count = call_params->GetParamsCount(); 113 param_count = call_params->GetParamsCount();
110 if ((buffer_size - sizeof(CrossCallParams)) < 114
111 (sizeof(ptrdiff_t) * (param_count + 1))) { 115 min_declared_size =
112 // This test is subject to integer overflow but the next is not. 116 sizeof(CrossCallParamsEx) + (param_count * sizeof(ParamInfo));
117
118 if ((buffer_size < min_declared_size) ||
119 (sizeof(CrossCallParamsEx) > min_declared_size)) {
120 // Minimal computed size bigger than existing buffer or param_count
121 // integer overflow.
113 return NULL; 122 return NULL;
114 } 123 }
115 124
116 actual_size = GetActualBufferSize(param_count, buffer_base); 125 // Retrieve the declared size which if it fails returns 0.
117 if ((actual_size > buffer_size) || (0 == actual_size)) { 126 declared_size = GetActualBufferSize(param_count, buffer_base);
118 // It is too big or too many declared parameters. 127
128 if ((declared_size > buffer_size) ||
129 (declared_size < min_declared_size)) {
130 // Declared size is bigger than buffer or smaller than computed size
131 // or param_count 0 or bigger than 9.
119 return NULL; 132 return NULL;
120 } 133 }
121 134
122 // Now we copy the actual amount of the message. 135 // Now we copy the actual amount of the message.
123 actual_size += sizeof(ParamInfo); // To get the last offset. 136 *output_size = declared_size;
124 *output_size = actual_size; 137 backing_mem = new char[declared_size];
125 backing_mem = new char[actual_size]; 138 copied_params = reinterpret_cast<CrossCallParamsEx*>(backing_mem);
126 memset(backing_mem, 0, actual_size); 139 memcpy(backing_mem, call_params, declared_size);
127 // Note that this is a placement new.
128 #pragma warning(push)
129 #pragma warning(disable: 4291) // No matching operator delete.
130 // TODO(cpu): Remove this warning.
131 copied_params = new(backing_mem)CrossCallParamsEx();
132 #pragma warning(pop)
133 memcpy(backing_mem, call_params, actual_size);
134 140
135 } __except(EXCEPTION_EXECUTE_HANDLER) { 141 } __except(EXCEPTION_EXECUTE_HANDLER) {
136 // In case of a windows exception we know it occurred while touching the 142 // In case of a windows exception we know it occurred while touching the
137 // untrusted buffer so we bail out as is. 143 // untrusted buffer so we bail out as is.
144 delete [] backing_mem;
138 return NULL; 145 return NULL;
139 } 146 }
140 147
141 char* last_byte = &backing_mem[actual_size - 1]; 148 const char* last_byte = &backing_mem[declared_size];
149 const char* first_byte = &backing_mem[min_declared_size];
150
142 // Verify here that all and each parameters make sense. This is done in the 151 // Verify here that all and each parameters make sense. This is done in the
143 // local copy. 152 // local copy.
144 for (size_t ix =0; ix != param_count; ++ix) { 153 for (size_t ix =0; ix != param_count; ++ix) {
145 size_t size = 0; 154 size_t size = 0;
146 ArgType type; 155 ArgType type;
147 char* address = reinterpret_cast<char*>( 156 char* address = reinterpret_cast<char*>(
148 copied_params->GetRawParameter(ix, &size, &type)); 157 copied_params->GetRawParameter(ix, &size, &type));
149 if ((NULL == address) || // No null params. 158 if ((NULL == address) || // No null params.
150 (INVALID_TYPE >= type) || (LAST_TYPE <= type) || // Unknown type. 159 (INVALID_TYPE >= type) || (LAST_TYPE <= type) || // Unknown type.
151 (address < backing_mem) || // Start cannot point before buffer. 160 (address < backing_mem) || // Start cannot point before buffer.
161 (address < first_byte) || // Start cannot point too low.
152 (address > last_byte) || // Start cannot point past buffer. 162 (address > last_byte) || // Start cannot point past buffer.
153 ((address + size) < address) || // Invalid size. 163 ((address + size) < address) || // Invalid size.
154 ((address + size) > last_byte)) { // End cannot point past buffer. 164 ((address + size) > last_byte)) { // End cannot point past buffer.
155 // Malformed. 165 // Malformed.
156 delete[] backing_mem; 166 delete[] backing_mem;
157 return NULL; 167 return NULL;
158 } 168 }
159 } 169 }
160 // The parameter buffer looks good. 170 // The parameter buffer looks good.
161 return copied_params; 171 return copied_params;
162 } 172 }
163 173
164 // Accessors to the parameters in the raw buffer. 174 // Accessors to the parameters in the raw buffer.
165 void* CrossCallParamsEx::GetRawParameter(size_t index, size_t* size, 175 void* CrossCallParamsEx::GetRawParameter(size_t index, size_t* size,
166 ArgType* type) { 176 ArgType* type) {
167 if (index > GetParamsCount()) { 177 if (index >= GetParamsCount()) {
168 return NULL; 178 return NULL;
169 } 179 }
170 // The size is always computed from the parameter minus the next 180 // The size is always computed from the parameter minus the next
171 // parameter, this works because the message has an extra parameter slot 181 // parameter, this works because the message has an extra parameter slot
172 *size = param_info_[index].size_; 182 *size = param_info_[index].size_;
173 *type = param_info_[index].type_; 183 *type = param_info_[index].type_;
174 184
175 return param_info_[index].offset_ + reinterpret_cast<char*>(this); 185 return param_info_[index].offset_ + reinterpret_cast<char*>(this);
176 } 186 }
177 187
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 for (; it != ipc_calls_.end(); ++it) { 266 for (; it != ipc_calls_.end(); ++it) {
257 if (it->params.Matches(ipc)) { 267 if (it->params.Matches(ipc)) {
258 *callback = it->callback; 268 *callback = it->callback;
259 return this; 269 return this;
260 } 270 }
261 } 271 }
262 return NULL; 272 return NULL;
263 } 273 }
264 274
265 } // namespace sandbox 275 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/src/crosscall_params.h ('k') | sandbox/src/ipc_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698