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

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: 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
« mojo/system/transport_data.h ('K') | « 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 for (size_t i = 0; i < platform_handles_->size(); i++)
199 (*platform_handles_)[i].CloseIfNecessary(); 199 (*platform_handles_)[i].CloseIfNecessary();
200 } 200 }
201 } 201 }
202 202
203 // static 203 // static
204 const char* TransportData::ValidateBuffer(const void* buffer, 204 const char* TransportData::ValidateBuffer(
205 size_t buffer_size) { 205 size_t serialized_platform_handle_size,
206 const void* buffer,
207 size_t buffer_size) {
206 DCHECK(buffer); 208 DCHECK(buffer);
207 DCHECK_GT(buffer_size, 0u); 209 DCHECK_GT(buffer_size, 0u);
208 210
209 // Always make sure that the buffer size is sane; if it's not, someone's 211 // Always make sure that the buffer size is sane; if it's not, someone's
210 // messing with us. 212 // messing with us.
211 if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize || 213 if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize ||
212 buffer_size % MessageInTransit::kMessageAlignment != 0) 214 buffer_size % MessageInTransit::kMessageAlignment != 0)
213 return "Invalid message secondary buffer size"; 215 return "Invalid message secondary buffer size";
214 216
215 const Header* header = static_cast<const Header*>(buffer); 217 const Header* header = static_cast<const Header*>(buffer);
216 const size_t num_handles = header->num_handles; 218 const size_t num_handles = header->num_handles;
217 if (num_handles == 0) 219 if (num_handles == 0)
218 return "Message has no handles attached, but secondary buffer present"; 220 return "Message has no handles attached, but secondary buffer present";
219 221
220 // Sanity-check |num_handles| (before multiplying it against anything). 222 // Sanity-check |num_handles| (before multiplying it against anything).
221 if (num_handles > kMaxMessageNumHandles) 223 if (num_handles > kMaxMessageNumHandles)
222 return "Message handle payload too large"; 224 return "Message handle payload too large";
223 225
224 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry)) 226 if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry))
225 return "Message secondary buffer too small"; 227 return "Message secondary buffer too small";
226 228
227 // TODO(vtl): Check |platform_handle_table_offset| and |num_platform_handles| 229 if (header->num_platform_handles == 0) {
228 // once they're used. 230 // Then |platform_handle_table_offset| should also be zero.
229 if (header->platform_handle_table_offset != 0 || 231 if (header->platform_handle_table_offset != 0) {
230 header->num_platform_handles != 0) 232 return
231 return "Bad message secondary buffer header values"; 233 "Message has no handles attached, but platform handle table present";
234 }
235 } else {
236 // |num_handles| has already been validated, so the multiplication is okay.
237 if (header->num_platform_handles >
238 num_handles * kMaxSerializedDispatcherPlatformHandles)
239 return "Message has too many platform handles attached";
240
241 static const char kInvalidPlatformHandleTableOffset[] =
242 "Message has invalid platform handle table offset";
243 // This doesn't check that the platform handle table doesn't alias other
244 // stuff, but it doesn't matter, since it's all read-only.
245 if (header->platform_handle_table_offset %
246 MessageInTransit::kMessageAlignment != 0)
247 return kInvalidPlatformHandleTableOffset;
248
249 // ">" instead of ">=" since the size per handle may be zero.
250 if (header->platform_handle_table_offset > buffer_size)
251 return kInvalidPlatformHandleTableOffset;
252
253 // We already checked |platform_handle_table_offset| and
254 // |num_platform_handles|, so the addition and multiplication are okay.
255 if (header->platform_handle_table_offset +
256 header->num_platform_handles * serialized_platform_handle_size >
257 buffer_size)
258 return kInvalidPlatformHandleTableOffset;
259 }
232 260
233 const HandleTableEntry* handle_table = 261 const HandleTableEntry* handle_table =
234 reinterpret_cast<const HandleTableEntry*>( 262 reinterpret_cast<const HandleTableEntry*>(
235 static_cast<const char*>(buffer) + sizeof(Header)); 263 static_cast<const char*>(buffer) + sizeof(Header));
236 static const char kInvalidSerializedDispatcher[] = 264 static const char kInvalidSerializedDispatcher[] =
237 "Message contains invalid serialized dispatcher"; 265 "Message contains invalid serialized dispatcher";
238 for (size_t i = 0; i < num_handles; i++) { 266 for (size_t i = 0; i < num_handles; i++) {
239 size_t offset = handle_table[i].offset; 267 size_t offset = handle_table[i].offset;
240 if (offset % MessageInTransit::kMessageAlignment != 0) 268 if (offset % MessageInTransit::kMessageAlignment != 0)
241 return kInvalidSerializedDispatcher; 269 return kInvalidSerializedDispatcher;
242 270
243 size_t size = handle_table[i].size; 271 size_t size = handle_table[i].size;
244 if (size > kMaxSerializedDispatcherSize || size > buffer_size) 272 if (size > kMaxSerializedDispatcherSize || size > buffer_size)
245 return kInvalidSerializedDispatcher; 273 return kInvalidSerializedDispatcher;
246 274
247 // Note: This is an overflow-safe check for |offset + size > buffer_size| 275 // Note: This is an overflow-safe check for |offset + size > buffer_size|
248 // (we know that |size <= buffer_size| from the previous check). 276 // (we know that |size <= buffer_size| from the previous check).
249 if (offset > buffer_size - size) 277 if (offset > buffer_size - size)
250 return kInvalidSerializedDispatcher; 278 return kInvalidSerializedDispatcher;
251 } 279 }
252 280
253 return NULL; 281 return NULL;
254 } 282 }
255 283
256 // static 284 // static
285 void TransportData::GetPlatformHandleTable(const void* transport_data_buffer,
286 size_t* num_platform_handles,
287 const void** platform_handle_table) {
288 DCHECK(transport_data_buffer);
289 DCHECK(num_platform_handles);
290 DCHECK(platform_handle_table);
291
292 const Header* header = static_cast<const Header*>(transport_data_buffer);
293 *num_platform_handles = header->num_platform_handles;
294 *platform_handle_table = static_cast<const char*>(transport_data_buffer) +
295 header->platform_handle_table_offset;
296 }
297
298 // static
257 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchersFromBuffer( 299 scoped_ptr<DispatcherVector> TransportData::DeserializeDispatchersFromBuffer(
258 const void* buffer, 300 const void* buffer,
259 size_t buffer_size, 301 size_t buffer_size,
260 Channel* channel) { 302 Channel* channel) {
261 DCHECK(buffer); 303 DCHECK(buffer);
262 DCHECK_GT(buffer_size, 0u); 304 DCHECK_GT(buffer_size, 0u);
263 DCHECK(channel); 305 DCHECK(channel);
264 306
265 const Header* header = static_cast<const Header*>(buffer); 307 const Header* header = static_cast<const Header*>(buffer);
266 const size_t num_handles = header->num_handles; 308 const size_t num_handles = header->num_handles;
(...skipping 13 matching lines...) Expand all
280 const void* source = static_cast<const char*>(buffer) + offset; 322 const void* source = static_cast<const char*>(buffer) + offset;
281 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize( 323 (*dispatchers)[i] = Dispatcher::TransportDataAccess::Deserialize(
282 channel, handle_table[i].type, source, size); 324 channel, handle_table[i].type, source, size);
283 } 325 }
284 326
285 return dispatchers.Pass(); 327 return dispatchers.Pass();
286 } 328 }
287 329
288 } // namespace system 330 } // namespace system
289 } // namespace mojo 331 } // namespace mojo
OLDNEW
« mojo/system/transport_data.h ('K') | « mojo/system/transport_data.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698