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

Side by Side Diff: mojo/system/transport_data.cc

Issue 277083003: Mojo: (Theoretically) implement the read side of platform handle passing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: asdf Created 6 years, 7 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 | « mojo/system/transport_data.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "mojo/system/transport_data.h" 5 #include "mojo/system/transport_data.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 187 }
188 188
189 // There's no aligned realloc, so it's no good way to release unused space (if 189 // There's no aligned realloc, so it's no good way to release unused space (if
190 // we overshot our estimated space requirements). 190 // we overshot our estimated space requirements).
191 buffer_size_ = current_offset; 191 buffer_size_ = current_offset;
192 192
193 // |dispatchers_| will be destroyed as it goes out of scope. 193 // |dispatchers_| will be destroyed as it goes out of scope.
194 } 194 }
195 195
196 TransportData::~TransportData() { 196 TransportData::~TransportData() {
197 if (platform_handles_) { 197 if (platform_handles_)
198 for (size_t i = 0; i < platform_handles_->size(); i++) 198 embedder::CloseAllHandlesAndClear(platform_handles_.get());
199 (*platform_handles_)[i].CloseIfNecessary();
200 }
201 } 199 }
202 200
203 // static 201 // static
204 const char* TransportData::ValidateBuffer(const void* buffer, 202 const char* TransportData::ValidateBuffer(
205 size_t buffer_size) { 203 size_t serialized_platform_handle_size,
204 const void* buffer,
205 size_t buffer_size) {
206 DCHECK(buffer); 206 DCHECK(buffer);
207 DCHECK_GT(buffer_size, 0u); 207 DCHECK_GT(buffer_size, 0u);
208 208
209 // Always make sure that the buffer size is sane; if it's not, someone's 209 // Always make sure that the buffer size is sane; if it's not, someone's
210 // messing with us. 210 // messing with us.
211 if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize || 211 if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize ||
212 buffer_size % MessageInTransit::kMessageAlignment != 0) 212 buffer_size % MessageInTransit::kMessageAlignment != 0)
213 return "Invalid message secondary buffer size"; 213 return "Invalid message secondary buffer size";
214 214
215 const Header* header = static_cast<const Header*>(buffer); 215 const Header* header = static_cast<const Header*>(buffer);
216 const size_t num_handles = header->num_handles; 216 const size_t num_handles = header->num_handles;
217 if (num_handles == 0) 217 if (num_handles == 0)
218 return "Message has no handles attached, but secondary buffer present"; 218 return "Message has no handles attached, but secondary buffer present";
219 219
220 // Sanity-check |num_handles| (before multiplying it against anything). 220 // Sanity-check |num_handles| (before multiplying it against anything).
221 if (num_handles > kMaxMessageNumHandles) 221 if (num_handles > kMaxMessageNumHandles)
222 return "Message handle payload too large"; 222 return "Message handle payload too large";
223 223
224 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry)) 224 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry))
225 return "Message secondary buffer too small"; 225 return "Message secondary buffer too small";
226 226
227 // TODO(vtl): Check |platform_handle_table_offset| and |num_platform_handles| 227 if (header->num_platform_handles == 0) {
228 // once they're used. 228 // Then |platform_handle_table_offset| should also be zero.
229 if (header->platform_handle_table_offset != 0 || 229 if (header->platform_handle_table_offset != 0) {
230 header->num_platform_handles != 0) 230 return
231 return "Bad message secondary buffer header values"; 231 "Message has no handles attached, but platform handle table present";
232 }
233 } else {
234 // |num_handles| has already been validated, so the multiplication is okay.
235 if (header->num_platform_handles >
236 num_handles * kMaxSerializedDispatcherPlatformHandles)
237 return "Message has too many platform handles attached";
238
239 static const char kInvalidPlatformHandleTableOffset[] =
240 "Message has invalid platform handle table offset";
241 // This doesn't check that the platform handle table doesn't alias other
242 // stuff, but it doesn't matter, since it's all read-only.
243 if (header->platform_handle_table_offset %
244 MessageInTransit::kMessageAlignment != 0)
245 return kInvalidPlatformHandleTableOffset;
246
247 // ">" instead of ">=" since the size per handle may be zero.
248 if (header->platform_handle_table_offset > buffer_size)
249 return kInvalidPlatformHandleTableOffset;
250
251 // We already checked |platform_handle_table_offset| and
252 // |num_platform_handles|, so the addition and multiplication are okay.
253 if (header->platform_handle_table_offset +
254 header->num_platform_handles * serialized_platform_handle_size >
255 buffer_size)
256 return kInvalidPlatformHandleTableOffset;
257 }
232 258
233 const HandleTableEntry* handle_table = 259 const HandleTableEntry* handle_table =
234 reinterpret_cast<const HandleTableEntry*>( 260 reinterpret_cast<const HandleTableEntry*>(
235 static_cast<const char*>(buffer) + sizeof(Header)); 261 static_cast<const char*>(buffer) + sizeof(Header));
236 static const char kInvalidSerializedDispatcher[] = 262 static const char kInvalidSerializedDispatcher[] =
237 "Message contains invalid serialized dispatcher"; 263 "Message contains invalid serialized dispatcher";
238 for (size_t i = 0; i < num_handles; i++) { 264 for (size_t i = 0; i < num_handles; i++) {
239 size_t offset = handle_table[i].offset; 265 size_t offset = handle_table[i].offset;
240 if (offset % MessageInTransit::kMessageAlignment != 0) 266 if (offset % MessageInTransit::kMessageAlignment != 0)
241 return kInvalidSerializedDispatcher; 267 return kInvalidSerializedDispatcher;
242 268
243 size_t size = handle_table[i].size; 269 size_t size = handle_table[i].size;
244 if (size > kMaxSerializedDispatcherSize || size > buffer_size) 270 if (size > kMaxSerializedDispatcherSize || size > buffer_size)
245 return kInvalidSerializedDispatcher; 271 return kInvalidSerializedDispatcher;
246 272
247 // Note: This is an overflow-safe check for |offset + size > buffer_size| 273 // Note: This is an overflow-safe check for |offset + size > buffer_size|
248 // (we know that |size <= buffer_size| from the previous check). 274 // (we know that |size <= buffer_size| from the previous check).
249 if (offset > buffer_size - size) 275 if (offset > buffer_size - size)
250 return kInvalidSerializedDispatcher; 276 return kInvalidSerializedDispatcher;
251 } 277 }
252 278
253 return NULL; 279 return NULL;
254 } 280 }
255 281
256 // static 282 // static
283 void TransportData::GetPlatformHandleTable(const void* transport_data_buffer,
284 size_t* num_platform_handles,
285 const void** platform_handle_table) {
286 DCHECK(transport_data_buffer);
287 DCHECK(num_platform_handles);
288 DCHECK(platform_handle_table);
289
290 const Header* header = static_cast<const Header*>(transport_data_buffer);
291 *num_platform_handles = header->num_platform_handles;
292 *platform_handle_table = static_cast<const char*>(transport_data_buffer) +
293 header->platform_handle_table_offset;
294 }
295
296 // static
257 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchersFromBuffer( 297 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchersFromBuffer(
258 const void* buffer, 298 const void* buffer,
259 size_t buffer_size, 299 size_t buffer_size,
260 Channel* channel) { 300 Channel* channel) {
261 DCHECK(buffer); 301 DCHECK(buffer);
262 DCHECK_GT(buffer_size, 0u); 302 DCHECK_GT(buffer_size, 0u);
263 DCHECK(channel); 303 DCHECK(channel);
264 304
265 const Header* header = static_cast<const Header*>(buffer); 305 const Header* header = static_cast<const Header*>(buffer);
266 const size_t num_handles = header->num_handles; 306 const size_t num_handles = header->num_handles;
(...skipping 13 matching lines...) Expand all
280 const void* source = static_cast<const char*>(buffer) + offset; 320 const void* source = static_cast<const char*>(buffer) + offset;
281 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( 321 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize(
282 channel, handle_table[i].type, source, size); 322 channel, handle_table[i].type, source, size);
283 } 323 }
284 324
285 return dispatchers.Pass(); 325 return dispatchers.Pass();
286 } 326 }
287 327
288 } // namespace system 328 } // namespace system
289 } // namespace mojo 329 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/transport_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698