| OLD | NEW |
| 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 Loading... |
| 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. | |
| 90 if (NULL == buffer_base) { | 88 if (NULL == buffer_base) { |
| 91 return NULL; | 89 return NULL; |
| 92 } | 90 } |
| 93 if (buffer_size < sizeof(CrossCallParams)) { | 91 if (buffer_size < sizeof(CrossCallParams)) { |
| 94 return NULL; | 92 return NULL; |
| 95 } | 93 } |
| 96 if (buffer_size > kMaxBufferSize) { | 94 if (buffer_size > kMaxBufferSize) { |
| 97 return NULL; | 95 return NULL; |
| 98 } | 96 } |
| 99 | |
| 100 char* backing_mem = NULL; | 97 char* backing_mem = NULL; |
| 101 size_t param_count = 0; | 98 size_t param_count = 0; |
| 102 size_t declared_size; | |
| 103 size_t min_declared_size; | |
| 104 CrossCallParamsEx* copied_params = NULL; | 99 CrossCallParamsEx* copied_params = NULL; |
| 100 size_t actual_size; |
| 105 | 101 |
| 106 // Touching the untrusted buffer is done under a SEH try block. This | 102 // Touching the untrusted buffer is done under a SEH try block. This |
| 107 // will catch memory access violations so we don't crash. | 103 // will catch memory access violations so we don't crash. |
| 108 __try { | 104 __try { |
| 109 CrossCallParams* call_params = | 105 CrossCallParams* call_params = |
| 110 reinterpret_cast<CrossCallParams*>(buffer_base); | 106 reinterpret_cast<CrossCallParams*>(buffer_base); |
| 111 // Check against the minimum size given the number of stated params | 107 // Check against the minimum size given the number of stated params |
| 112 // if too small we bail out. | 108 // if too small we bail out. |
| 113 param_count = call_params->GetParamsCount(); | 109 param_count = call_params->GetParamsCount(); |
| 114 | 110 if ((buffer_size - sizeof(CrossCallParams)) < |
| 115 min_declared_size = | 111 (sizeof(ptrdiff_t) * (param_count + 1))) { |
| 116 sizeof(CrossCallParamsEx) + (param_count * sizeof(ParamInfo)); | 112 // This test is subject to integer overflow but the next is not. |
| 117 | |
| 118 if (min_declared_size < sizeof(CrossCallParams) || | |
| 119 (buffer_size < min_declared_size)) { | |
| 120 // Integer overflow or computed size bigger than untrusted buffer. | |
| 121 return NULL; | 113 return NULL; |
| 122 } | 114 } |
| 123 | 115 |
| 124 declared_size = GetActualBufferSize(param_count, buffer_base); | 116 actual_size = GetActualBufferSize(param_count, buffer_base); |
| 125 if ((declared_size > buffer_size) || | 117 if ((actual_size > buffer_size) || (0 == actual_size)) { |
| 126 (declared_size < min_declared_size)) { | 118 // It is too big or too many declared parameters. |
| 127 // declared size is bigger than buffer or smaller than computed size. | |
| 128 return NULL; | 119 return NULL; |
| 129 } | 120 } |
| 130 | 121 |
| 131 // Now we copy the actual amount of the message. | 122 // Now we copy the actual amount of the message. |
| 132 *output_size = declared_size; | 123 actual_size += sizeof(ParamInfo); // To get the last offset. |
| 133 backing_mem = new char[declared_size]; | 124 *output_size = actual_size; |
| 134 copied_params = reinterpret_cast<CrossCallParamsEx*>(backing_mem); | 125 backing_mem = new char[actual_size]; |
| 135 memcpy(backing_mem, call_params, declared_size); | 126 memset(backing_mem, 0, actual_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); |
| 136 | 134 |
| 137 } __except(EXCEPTION_EXECUTE_HANDLER) { | 135 } __except(EXCEPTION_EXECUTE_HANDLER) { |
| 138 // In case of a windows exception we know it occurred while touching the | 136 // In case of a windows exception we know it occurred while touching the |
| 139 // untrusted buffer so we bail out as is. | 137 // untrusted buffer so we bail out as is. |
| 140 return NULL; | 138 return NULL; |
| 141 } | 139 } |
| 142 | 140 |
| 143 const char* last_byte = &backing_mem[declared_size - 1]; | 141 char* last_byte = &backing_mem[actual_size - 1]; |
| 144 const char* first_byte = &backing_mem[min_declared_size]; | |
| 145 | |
| 146 // Verify here that all and each parameters make sense. This is done in the | 142 // Verify here that all and each parameters make sense. This is done in the |
| 147 // local copy. | 143 // local copy. |
| 148 for (size_t ix =0; ix != param_count; ++ix) { | 144 for (size_t ix =0; ix != param_count; ++ix) { |
| 149 size_t size = 0; | 145 size_t size = 0; |
| 150 ArgType type; | 146 ArgType type; |
| 151 char* address = reinterpret_cast<char*>( | 147 char* address = reinterpret_cast<char*>( |
| 152 copied_params->GetRawParameter(ix, &size, &type)); | 148 copied_params->GetRawParameter(ix, &size, &type)); |
| 153 if ((NULL == address) || // No null params. | 149 if ((NULL == address) || // No null params. |
| 154 (INVALID_TYPE >= type) || (LAST_TYPE <= type) || // Unknown type. | 150 (INVALID_TYPE >= type) || (LAST_TYPE <= type) || // Unknown type. |
| 155 (address < backing_mem) || // Start cannot point before buffer. | 151 (address < backing_mem) || // Start cannot point before buffer. |
| 156 (address < first_byte) || // Start cannot point too low. | |
| 157 (address > last_byte) || // Start cannot point past buffer. | 152 (address > last_byte) || // Start cannot point past buffer. |
| 158 ((address + size) < address) || // Invalid size. | 153 ((address + size) < address) || // Invalid size. |
| 159 ((address + size) > last_byte)) { // End cannot point past buffer. | 154 ((address + size) > last_byte)) { // End cannot point past buffer. |
| 160 // Malformed. | 155 // Malformed. |
| 161 delete[] backing_mem; | 156 delete[] backing_mem; |
| 162 return NULL; | 157 return NULL; |
| 163 } | 158 } |
| 164 } | 159 } |
| 165 // The parameter buffer looks good. | 160 // The parameter buffer looks good. |
| 166 return copied_params; | 161 return copied_params; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 for (; it != ipc_calls_.end(); ++it) { | 256 for (; it != ipc_calls_.end(); ++it) { |
| 262 if (it->params.Matches(ipc)) { | 257 if (it->params.Matches(ipc)) { |
| 263 *callback = it->callback; | 258 *callback = it->callback; |
| 264 return this; | 259 return this; |
| 265 } | 260 } |
| 266 } | 261 } |
| 267 return NULL; | 262 return NULL; |
| 268 } | 263 } |
| 269 | 264 |
| 270 } // namespace sandbox | 265 } // namespace sandbox |
| OLD | NEW |