summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/win/src/ipc_args.cc
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/ipc_args.cc')
-rw-r--r--security/sandbox/chromium/sandbox/win/src/ipc_args.cc96
1 files changed, 96 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/ipc_args.cc b/security/sandbox/chromium/sandbox/win/src/ipc_args.cc
new file mode 100644
index 0000000000..c0c64f1864
--- /dev/null
+++ b/security/sandbox/chromium/sandbox/win/src/ipc_args.cc
@@ -0,0 +1,96 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sandbox/win/src/ipc_args.h"
+
+#include <stddef.h>
+
+#include "sandbox/win/src/crosscall_params.h"
+#include "sandbox/win/src/crosscall_server.h"
+
+namespace sandbox {
+
+// Releases memory allocated for IPC arguments, if needed.
+void ReleaseArgs(const IPCParams* ipc_params, void* args[kMaxIpcParams]) {
+ for (size_t i = 0; i < kMaxIpcParams; i++) {
+ switch (ipc_params->args[i]) {
+ case WCHAR_TYPE: {
+ delete reinterpret_cast<std::wstring*>(args[i]);
+ args[i] = nullptr;
+ break;
+ }
+ case INPTR_TYPE:
+ case INOUTPTR_TYPE: {
+ delete reinterpret_cast<CountedBuffer*>(args[i]);
+ args[i] = nullptr;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+// Fills up the list of arguments (args and ipc_params) for an IPC call.
+bool GetArgs(CrossCallParamsEx* params,
+ IPCParams* ipc_params,
+ void* args[kMaxIpcParams]) {
+ if (kMaxIpcParams < params->GetParamsCount())
+ return false;
+
+ for (uint32_t i = 0; i < params->GetParamsCount(); i++) {
+ uint32_t size;
+ ArgType type;
+ args[i] = params->GetRawParameter(i, &size, &type);
+ if (args[i]) {
+ ipc_params->args[i] = type;
+ switch (type) {
+ case WCHAR_TYPE: {
+ std::unique_ptr<std::wstring> data(new std::wstring);
+ if (!params->GetParameterStr(i, data.get())) {
+ args[i] = 0;
+ ReleaseArgs(ipc_params, args);
+ return false;
+ }
+ args[i] = data.release();
+ break;
+ }
+ case UINT32_TYPE: {
+ uint32_t data;
+ if (!params->GetParameter32(i, &data)) {
+ ReleaseArgs(ipc_params, args);
+ return false;
+ }
+ IPCInt ipc_int(data);
+ args[i] = ipc_int.AsVoidPtr();
+ break;
+ }
+ case VOIDPTR_TYPE: {
+ void* data;
+ if (!params->GetParameterVoidPtr(i, &data)) {
+ ReleaseArgs(ipc_params, args);
+ return false;
+ }
+ args[i] = data;
+ break;
+ }
+ case INPTR_TYPE:
+ case INOUTPTR_TYPE: {
+ if (!args[i]) {
+ ReleaseArgs(ipc_params, args);
+ return false;
+ }
+ CountedBuffer* buffer = new CountedBuffer(args[i], size);
+ args[i] = buffer;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+} // namespace sandbox