| Index: sandbox/src/crosscall_server.cc
|
| ===================================================================
|
| --- sandbox/src/crosscall_server.cc (revision 37077)
|
| +++ sandbox/src/crosscall_server.cc (working copy)
|
| @@ -21,9 +21,9 @@
|
|
|
| namespace sandbox {
|
|
|
| -// Returns the actual size for the parameters in an IPC buffer.
|
| -void GetActualBufferSize(size_t param_count, void* buffer_base,
|
| - size_t* actual_size) {
|
| +// Returns the actual size for the parameters in an IPC buffer. Returns
|
| +// zero if the |param_count| is zero or too big.
|
| +size_t GetActualBufferSize(size_t param_count, void* buffer_base) {
|
| // The template types are used to calculate the maximum expected size.
|
| typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
|
| typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
|
| @@ -37,36 +37,29 @@
|
|
|
| // Retrieve the actual size and the maximum size of the params buffer.
|
| switch (param_count) {
|
| + case 0:
|
| + return 0;
|
| case 1:
|
| - *actual_size = reinterpret_cast<ActualCP1*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP1*>(buffer_base)->GetSize();
|
| case 2:
|
| - *actual_size = reinterpret_cast<ActualCP2*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP2*>(buffer_base)->GetSize();
|
| case 3:
|
| - *actual_size = reinterpret_cast<ActualCP3*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP3*>(buffer_base)->GetSize();
|
| case 4:
|
| - *actual_size = reinterpret_cast<ActualCP4*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP4*>(buffer_base)->GetSize();
|
| case 5:
|
| - *actual_size = reinterpret_cast<ActualCP5*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP5*>(buffer_base)->GetSize();
|
| case 6:
|
| - *actual_size = reinterpret_cast<ActualCP6*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP6*>(buffer_base)->GetSize();
|
| case 7:
|
| - *actual_size = reinterpret_cast<ActualCP7*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP7*>(buffer_base)->GetSize();
|
| case 8:
|
| - *actual_size = reinterpret_cast<ActualCP8*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP8*>(buffer_base)->GetSize();
|
| case 9:
|
| - *actual_size = reinterpret_cast<ActualCP9*>(buffer_base)->GetSize();
|
| - break;
|
| + return reinterpret_cast<ActualCP9*>(buffer_base)->GetSize();
|
| default:
|
| NOTREACHED();
|
| - *actual_size = 0;
|
| + return 0;
|
| }
|
| }
|
|
|
| @@ -104,9 +97,8 @@
|
| char* backing_mem = NULL;
|
| size_t param_count = 0;
|
| CrossCallParamsEx* copied_params = NULL;
|
| + size_t actual_size;
|
|
|
| - size_t actual_size = 0;
|
| -
|
| // Touching the untrusted buffer is done under a SEH try block. This
|
| // will catch memory access violations so we don't crash.
|
| __try {
|
| @@ -117,16 +109,16 @@
|
| param_count = call_params->GetParamsCount();
|
| if ((buffer_size - sizeof(CrossCallParams)) <
|
| (sizeof(ptrdiff_t) * (param_count + 1))) {
|
| - // Too small.
|
| + // This test is subject to integer overflow but the next is not.
|
| return NULL;
|
| }
|
|
|
| - GetActualBufferSize(param_count, buffer_base, &actual_size);
|
| -
|
| - if (actual_size > buffer_size) {
|
| - // It is too big.
|
| + actual_size = GetActualBufferSize(param_count, buffer_base);
|
| + if ((actual_size > buffer_size) || (0 == actual_size)) {
|
| + // It is too big or too many declared parameters.
|
| return NULL;
|
| }
|
| +
|
| // Now we copy the actual amount of the message.
|
| actual_size += sizeof(ParamInfo); // To get the last offset.
|
| *output_size = actual_size;
|
|
|