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 |