| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 | 12 |
| 13 // This code performs the ipc message validation. Potential security flaws | 13 // This code performs the ipc message validation. Potential security flaws |
| 14 // on the ipc are likelier to be found in this code than in the rest of | 14 // on the ipc are likelier to be found in this code than in the rest of |
| 15 // the ipc code. | 15 // the ipc code. |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 // The buffer for a message must match the max channel size. | 18 // The buffer for a message must match the max channel size. |
| 19 const size_t kMaxBufferSize = sandbox::kIPCChannelSize; | 19 const size_t kMaxBufferSize = sandbox::kIPCChannelSize; |
| 20 } | 20 } |
| 21 | 21 |
| 22 namespace sandbox { | 22 namespace sandbox { |
| 23 | 23 |
| 24 // Returns the actual size for the parameters in an IPC buffer. | 24 // Returns the actual size for the parameters in an IPC buffer. Returns |
| 25 void GetActualBufferSize(size_t param_count, void* buffer_base, | 25 // zero if the |param_count| is zero or too big. |
| 26 size_t* actual_size) { | 26 size_t GetActualBufferSize(size_t param_count, void* buffer_base) { |
| 27 // The template types are used to calculate the maximum expected size. | 27 // The template types are used to calculate the maximum expected size. |
| 28 typedef ActualCallParams<1, kMaxBufferSize> ActualCP1; | 28 typedef ActualCallParams<1, kMaxBufferSize> ActualCP1; |
| 29 typedef ActualCallParams<2, kMaxBufferSize> ActualCP2; | 29 typedef ActualCallParams<2, kMaxBufferSize> ActualCP2; |
| 30 typedef ActualCallParams<3, kMaxBufferSize> ActualCP3; | 30 typedef ActualCallParams<3, kMaxBufferSize> ActualCP3; |
| 31 typedef ActualCallParams<4, kMaxBufferSize> ActualCP4; | 31 typedef ActualCallParams<4, kMaxBufferSize> ActualCP4; |
| 32 typedef ActualCallParams<5, kMaxBufferSize> ActualCP5; | 32 typedef ActualCallParams<5, kMaxBufferSize> ActualCP5; |
| 33 typedef ActualCallParams<6, kMaxBufferSize> ActualCP6; | 33 typedef ActualCallParams<6, kMaxBufferSize> ActualCP6; |
| 34 typedef ActualCallParams<7, kMaxBufferSize> ActualCP7; | 34 typedef ActualCallParams<7, kMaxBufferSize> ActualCP7; |
| 35 typedef ActualCallParams<8, kMaxBufferSize> ActualCP8; | 35 typedef ActualCallParams<8, kMaxBufferSize> ActualCP8; |
| 36 typedef ActualCallParams<9, kMaxBufferSize> ActualCP9; | 36 typedef ActualCallParams<9, kMaxBufferSize> ActualCP9; |
| 37 | 37 |
| 38 // Retrieve the actual size and the maximum size of the params buffer. | 38 // Retrieve the actual size and the maximum size of the params buffer. |
| 39 switch (param_count) { | 39 switch (param_count) { |
| 40 case 0: |
| 41 return 0; |
| 40 case 1: | 42 case 1: |
| 41 *actual_size = reinterpret_cast<ActualCP1*>(buffer_base)->GetSize(); | 43 return reinterpret_cast<ActualCP1*>(buffer_base)->GetSize(); |
| 42 break; | |
| 43 case 2: | 44 case 2: |
| 44 *actual_size = reinterpret_cast<ActualCP2*>(buffer_base)->GetSize(); | 45 return reinterpret_cast<ActualCP2*>(buffer_base)->GetSize(); |
| 45 break; | |
| 46 case 3: | 46 case 3: |
| 47 *actual_size = reinterpret_cast<ActualCP3*>(buffer_base)->GetSize(); | 47 return reinterpret_cast<ActualCP3*>(buffer_base)->GetSize(); |
| 48 break; | |
| 49 case 4: | 48 case 4: |
| 50 *actual_size = reinterpret_cast<ActualCP4*>(buffer_base)->GetSize(); | 49 return reinterpret_cast<ActualCP4*>(buffer_base)->GetSize(); |
| 51 break; | |
| 52 case 5: | 50 case 5: |
| 53 *actual_size = reinterpret_cast<ActualCP5*>(buffer_base)->GetSize(); | 51 return reinterpret_cast<ActualCP5*>(buffer_base)->GetSize(); |
| 54 break; | |
| 55 case 6: | 52 case 6: |
| 56 *actual_size = reinterpret_cast<ActualCP6*>(buffer_base)->GetSize(); | 53 return reinterpret_cast<ActualCP6*>(buffer_base)->GetSize(); |
| 57 break; | |
| 58 case 7: | 54 case 7: |
| 59 *actual_size = reinterpret_cast<ActualCP7*>(buffer_base)->GetSize(); | 55 return reinterpret_cast<ActualCP7*>(buffer_base)->GetSize(); |
| 60 break; | |
| 61 case 8: | 56 case 8: |
| 62 *actual_size = reinterpret_cast<ActualCP8*>(buffer_base)->GetSize(); | 57 return reinterpret_cast<ActualCP8*>(buffer_base)->GetSize(); |
| 63 break; | |
| 64 case 9: | 58 case 9: |
| 65 *actual_size = reinterpret_cast<ActualCP9*>(buffer_base)->GetSize(); | 59 return reinterpret_cast<ActualCP9*>(buffer_base)->GetSize(); |
| 66 break; | |
| 67 default: | 60 default: |
| 68 NOTREACHED(); | 61 NOTREACHED(); |
| 69 *actual_size = 0; | 62 return 0; |
| 70 } | 63 } |
| 71 } | 64 } |
| 72 | 65 |
| 73 CrossCallParamsEx::CrossCallParamsEx() | 66 CrossCallParamsEx::CrossCallParamsEx() |
| 74 :CrossCallParams(0, 0) { | 67 :CrossCallParams(0, 0) { |
| 75 } | 68 } |
| 76 | 69 |
| 77 // We override the delete operator because the object's backing memory | 70 // We override the delete operator because the object's backing memory |
| 78 // is hand allocated in CreateFromBuffer. We don't override the new operator | 71 // is hand allocated in CreateFromBuffer. We don't override the new operator |
| 79 // because the constructors are private so there is no way to mismatch | 72 // because the constructors are private so there is no way to mismatch |
| (...skipping 17 matching lines...) Expand all Loading... |
| 97 } | 90 } |
| 98 if (buffer_size < sizeof(CrossCallParams)) { | 91 if (buffer_size < sizeof(CrossCallParams)) { |
| 99 return NULL; | 92 return NULL; |
| 100 } | 93 } |
| 101 if (buffer_size > kMaxBufferSize) { | 94 if (buffer_size > kMaxBufferSize) { |
| 102 return NULL; | 95 return NULL; |
| 103 } | 96 } |
| 104 char* backing_mem = NULL; | 97 char* backing_mem = NULL; |
| 105 size_t param_count = 0; | 98 size_t param_count = 0; |
| 106 CrossCallParamsEx* copied_params = NULL; | 99 CrossCallParamsEx* copied_params = NULL; |
| 107 | 100 size_t actual_size; |
| 108 size_t actual_size = 0; | |
| 109 | 101 |
| 110 // 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 |
| 111 // will catch memory access violations so we don't crash. | 103 // will catch memory access violations so we don't crash. |
| 112 __try { | 104 __try { |
| 113 CrossCallParams* call_params = | 105 CrossCallParams* call_params = |
| 114 reinterpret_cast<CrossCallParams*>(buffer_base); | 106 reinterpret_cast<CrossCallParams*>(buffer_base); |
| 115 // Check against the minimum size given the number of stated params | 107 // Check against the minimum size given the number of stated params |
| 116 // if too small we bail out. | 108 // if too small we bail out. |
| 117 param_count = call_params->GetParamsCount(); | 109 param_count = call_params->GetParamsCount(); |
| 118 if ((buffer_size - sizeof(CrossCallParams)) < | 110 if ((buffer_size - sizeof(CrossCallParams)) < |
| 119 (sizeof(ptrdiff_t) * (param_count + 1))) { | 111 (sizeof(ptrdiff_t) * (param_count + 1))) { |
| 120 // Too small. | 112 // This test is subject to integer overflow but the next is not. |
| 121 return NULL; | 113 return NULL; |
| 122 } | 114 } |
| 123 | 115 |
| 124 GetActualBufferSize(param_count, buffer_base, &actual_size); | 116 actual_size = GetActualBufferSize(param_count, buffer_base); |
| 125 | 117 if ((actual_size > buffer_size) || (0 == actual_size)) { |
| 126 if (actual_size > buffer_size) { | 118 // It is too big or too many declared parameters. |
| 127 // It is too big. | |
| 128 return NULL; | 119 return NULL; |
| 129 } | 120 } |
| 121 |
| 130 // Now we copy the actual amount of the message. | 122 // Now we copy the actual amount of the message. |
| 131 actual_size += sizeof(ParamInfo); // To get the last offset. | 123 actual_size += sizeof(ParamInfo); // To get the last offset. |
| 132 *output_size = actual_size; | 124 *output_size = actual_size; |
| 133 backing_mem = new char[actual_size]; | 125 backing_mem = new char[actual_size]; |
| 134 memset(backing_mem, 0, actual_size); | 126 memset(backing_mem, 0, actual_size); |
| 135 // Note that this is a placement new. | 127 // Note that this is a placement new. |
| 136 #pragma warning(push) | 128 #pragma warning(push) |
| 137 #pragma warning(disable: 4291) // No matching operator delete. | 129 #pragma warning(disable: 4291) // No matching operator delete. |
| 138 // TODO(cpu): Remove this warning. | 130 // TODO(cpu): Remove this warning. |
| 139 copied_params = new(backing_mem)CrossCallParamsEx(); | 131 copied_params = new(backing_mem)CrossCallParamsEx(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 for (; it != ipc_calls_.end(); ++it) { | 245 for (; it != ipc_calls_.end(); ++it) { |
| 254 if (it->params.Matches(ipc)) { | 246 if (it->params.Matches(ipc)) { |
| 255 *callback = it->callback; | 247 *callback = it->callback; |
| 256 return this; | 248 return this; |
| 257 } | 249 } |
| 258 } | 250 } |
| 259 return NULL; | 251 return NULL; |
| 260 } | 252 } |
| 261 | 253 |
| 262 } // namespace sandbox | 254 } // namespace sandbox |
| OLD | NEW |