summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/sandbox/win
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium-shim/sandbox/win')
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h101
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/loggingTypes.h27
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/sandboxLogging.cpp89
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h50
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_common.h31
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.cc58
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.h38
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.cc108
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.h19
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.cc66
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.h35
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/sandbox_policy_diagnostic.h31
-rw-r--r--security/sandbox/chromium-shim/sandbox/win/src/sidestep_resolver.h58
13 files changed, 711 insertions, 0 deletions
diff --git a/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
new file mode 100644
index 0000000000..3c5f8eea89
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef security_sandbox_loggingCallbacks_h__
+#define security_sandbox_loggingCallbacks_h__
+
+#include <sstream>
+
+#include "mozilla/Logging.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/StaticPrefs_security.h"
+#include "mozilla/sandboxing/loggingTypes.h"
+#include "nsContentUtils.h"
+
+#include "mozilla/StackWalk.h"
+
+namespace mozilla {
+
+static LazyLogModule sSandboxTargetLog("SandboxTarget");
+
+#define LOG_D(...) MOZ_LOG(sSandboxTargetLog, LogLevel::Debug, (__VA_ARGS__))
+
+namespace sandboxing {
+
+// NS_WalkStackCallback to write a formatted stack frame to an ostringstream.
+static void
+StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
+ void* aClosure)
+{
+ std::ostringstream* stream = static_cast<std::ostringstream*>(aClosure);
+ MozCodeAddressDetails details;
+ char buf[1024];
+ MozDescribeCodeAddress(aPC, &details);
+ MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
+ *stream << std::endl << "--" << buf;
+ stream->flush();
+}
+
+// Log to the browser console and, if DEBUG build, stderr.
+static void
+Log(const char* aMessageType,
+ const char* aFunctionName,
+ const char* aContext,
+ const bool aShouldLogStackTrace = false,
+ const void* aFirstFramePC = nullptr)
+{
+ std::ostringstream msgStream;
+ msgStream << "Process Sandbox " << aMessageType << ": " << aFunctionName;
+ if (aContext) {
+ msgStream << " for : " << aContext;
+ }
+
+#if defined(MOZ_SANDBOX)
+ // We can only log the stack trace on process types where we know that the
+ // sandbox won't prevent it.
+ if (XRE_IsContentProcess() && aShouldLogStackTrace) {
+ auto stackTraceDepth =
+ StaticPrefs::security_sandbox_windows_log_stackTraceDepth();
+ if (stackTraceDepth) {
+ msgStream << std::endl << "Stack Trace:";
+ MozStackWalk(StackFrameToOStringStream, aFirstFramePC, stackTraceDepth,
+ &msgStream);
+ }
+ }
+#endif
+ std::string msg = msgStream.str();
+#if defined(DEBUG)
+ // Use NS_DebugBreak directly as we want child process prefix, but not source
+ // file or line number.
+ NS_DebugBreak(NS_DEBUG_WARNING, nullptr, msg.c_str(), nullptr, -1);
+#endif
+
+ if (nsContentUtils::IsInitialized()) {
+ nsContentUtils::LogMessageToConsole(msg.c_str());
+ }
+
+ // As we don't always have the facility to log to console use MOZ_LOG as well.
+ LOG_D("%s", msg.c_str());
+}
+
+// Initialize sandbox logging if required.
+static void
+InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
+{
+ if (!aProvideLogFunctionCb) {
+ return;
+ }
+
+ if (Preferences::GetBool("security.sandbox.logging.enabled") ||
+ PR_GetEnv("MOZ_SANDBOX_LOGGING")) {
+ aProvideLogFunctionCb(Log);
+ }
+}
+
+} // sandboxing
+} // mozilla
+
+#endif // security_sandbox_loggingCallbacks_h__
diff --git a/security/sandbox/chromium-shim/sandbox/win/loggingTypes.h b/security/sandbox/chromium-shim/sandbox/win/loggingTypes.h
new file mode 100644
index 0000000000..7b75648fc9
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/loggingTypes.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef security_sandbox_loggingTypes_h__
+#define security_sandbox_loggingTypes_h__
+
+#include <stdint.h>
+
+namespace mozilla {
+namespace sandboxing {
+
+// We are using callbacks here that are passed in from the core code to prevent
+// a circular dependency in the linking during the build.
+typedef void (*LogFunction) (const char* aMessageType,
+ const char* aFunctionName,
+ const char* aContext,
+ const bool aShouldLogStackTrace,
+ const void* aFirstFramePC);
+typedef void (*ProvideLogFunctionCb) (LogFunction aLogFunction);
+
+} // sandboxing
+} // mozilla
+
+#endif // security_sandbox_loggingTypes_h__
diff --git a/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.cpp b/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.cpp
new file mode 100644
index 0000000000..a556f9e772
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.cpp
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "sandboxLogging.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "sandbox/win/src/sandbox_policy.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/StackWalk.h"
+
+namespace mozilla {
+namespace sandboxing {
+
+static LogFunction sLogFunction = nullptr;
+
+void
+ProvideLogFunction(LogFunction aLogFunction)
+{
+ sLogFunction = aLogFunction;
+}
+
+static void
+LogBlocked(const char* aFunctionName, const char* aContext, const void* aFirstFramePC)
+{
+ if (sLogFunction) {
+ sLogFunction("BLOCKED", aFunctionName, aContext,
+ /* aShouldLogStackTrace */ true, aFirstFramePC);
+ }
+}
+
+MOZ_NEVER_INLINE void
+LogBlocked(const char* aFunctionName, const char* aContext)
+{
+ if (sLogFunction) {
+ LogBlocked(aFunctionName, aContext, CallerPC());
+ }
+}
+
+MOZ_NEVER_INLINE void
+LogBlocked(const char* aFunctionName, const wchar_t* aContext)
+{
+ if (sLogFunction) {
+ LogBlocked(aFunctionName, base::WideToUTF8(aContext).c_str(), CallerPC());
+ }
+}
+
+MOZ_NEVER_INLINE void
+LogBlocked(const char* aFunctionName, const wchar_t* aContext,
+ uint16_t aLengthInBytes)
+{
+ if (sLogFunction) {
+ LogBlocked(aFunctionName,
+ base::WideToUTF8(std::wstring(aContext, aLengthInBytes / sizeof(wchar_t))).c_str(),
+ CallerPC());
+ }
+}
+
+void
+LogAllowed(const char* aFunctionName, const char* aContext)
+{
+ if (sLogFunction) {
+ sLogFunction("Broker ALLOWED", aFunctionName, aContext,
+ /* aShouldLogStackTrace */ false, nullptr);
+ }
+}
+
+void
+LogAllowed(const char* aFunctionName, const wchar_t* aContext)
+{
+ if (sLogFunction) {
+ LogAllowed(aFunctionName, base::WideToUTF8(aContext).c_str());
+ }
+}
+
+void
+LogAllowed(const char* aFunctionName, const wchar_t* aContext,
+ uint16_t aLengthInBytes)
+{
+ if (sLogFunction) {
+ LogAllowed(aFunctionName,
+ base::WideToUTF8(std::wstring(aContext, aLengthInBytes / sizeof(wchar_t))).c_str());
+ }
+}
+
+} // sandboxing
+} // mozilla
diff --git a/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h b/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h
new file mode 100644
index 0000000000..31c4ddb076
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/sandboxLogging.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Set of helper methods to implement logging for Windows sandbox.
+ */
+
+#ifndef security_sandbox_sandboxLogging_h__
+#define security_sandbox_sandboxLogging_h__
+
+#include "loggingTypes.h"
+
+namespace sandbox {
+class TargetPolicy;
+}
+
+namespace mozilla {
+namespace sandboxing {
+
+// This is used to pass a LogCallback to the sandboxing code, as the logging
+// requires code to which we cannot link directly.
+void ProvideLogFunction(LogFunction aLogFunction);
+
+// Log a "BLOCKED" msg to the browser console and, if DEBUG build, stderr.
+// If the logging of a stack trace is enabled then a trace starting from the
+// caller of the relevant LogBlocked overload will be logged, which should
+// normally be the function that triggered the interception.
+void LogBlocked(const char* aFunctionName, const char* aContext = nullptr);
+
+// Convenience functions to convert to char*.
+void LogBlocked(const char* aFunctionName, const wchar_t* aContext);
+void LogBlocked(const char* aFunctionName, const wchar_t* aContext,
+ uint16_t aLengthInBytes);
+
+// Log a "ALLOWED" msg to the browser console and, if DEBUG build, stderr.
+void LogAllowed(const char* aFunctionName, const char* aContext = nullptr);
+
+// Convenience functions to convert to char*.
+void LogAllowed(const char* aFunctionName, const wchar_t* aContext);
+void LogAllowed(const char* aFunctionName, const wchar_t* aContext,
+ uint16_t aLengthInBytes);
+
+
+} // sandboxing
+} // mozilla
+
+#endif // security_sandbox_sandboxLogging_h__
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_common.h b/security/sandbox/chromium-shim/sandbox/win/src/line_break_common.h
new file mode 100644
index 0000000000..b712239dde
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_common.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SANDBOX_SRC_LINE_BREAK_COMMON_H_
+#define SANDBOX_SRC_LINE_BREAK_COMMON_H_
+
+#include "sandbox/win/src/crosscall_params.h"
+
+namespace sandbox {
+
+#if defined(MOZ_DEBUG)
+// Set a low max brokered length for testing to exercise the chunking code.
+static const std::ptrdiff_t kMaxBrokeredLen = 50;
+
+#else
+// Parameters are stored aligned to sizeof(int64_t).
+// So to calculate the maximum length we can use when brokering to the parent,
+// we take the max params buffer size, take off 8 for the aligned length and 6
+// and 7 to allow for the maximum padding that can be added to the text and
+// break before buffers. We then divide by three, because the text characters
+// are wchar_t and the break before elements are uint8_t.
+static const std::ptrdiff_t kMaxBrokeredLen =
+ (ActualCallParams<3, kIPCChannelSize>::MaxParamsSize() - 8 - 6 - 7) / 3;
+#endif
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_LINE_BREAK_COMMON_H_
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.cc b/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.cc
new file mode 100644
index 0000000000..94401d18fa
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.cc
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "sandbox/win/src/line_break_dispatcher.h"
+
+#include "sandbox/win/src/line_break_common.h"
+#include "sandbox/win/src/line_break_policy.h"
+#include "sandbox/win/src/ipc_tags.h"
+#include "sandbox/win/src/policy_params.h"
+
+namespace sandbox {
+
+LineBreakDispatcher::LineBreakDispatcher(PolicyBase* policy_base)
+ : policy_base_(policy_base) {
+ static const IPCCall get_complex_line_breaks = {
+ {IpcTag::GETCOMPLEXLINEBREAKS, {INPTR_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
+ reinterpret_cast<CallbackGeneric>(
+ &LineBreakDispatcher::GetComplexLineBreaksCall)};
+
+ ipc_calls_.push_back(get_complex_line_breaks);
+}
+
+bool LineBreakDispatcher::SetupService(InterceptionManager* manager,
+ IpcTag service) {
+ // We perform no interceptions for line breaking right now.
+ switch (service) {
+ case IpcTag::GETCOMPLEXLINEBREAKS:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool LineBreakDispatcher::GetComplexLineBreaksCall(
+ IPCInfo* ipc, CountedBuffer* text_buf, uint32_t length,
+ CountedBuffer* break_before_buf) {
+ if (length > kMaxBrokeredLen ||
+ text_buf->Size() != length * sizeof(wchar_t) ||
+ break_before_buf->Size() != length) {
+ return false;
+ }
+
+ CountedParameterSet<EmptyParams> params;
+ EvalResult eval =
+ policy_base_->EvalPolicy(IpcTag::GETCOMPLEXLINEBREAKS, params.GetBase());
+ auto* text = static_cast<wchar_t*>(text_buf->Buffer());
+ auto* break_before = static_cast<uint8_t*>(break_before_buf->Buffer());
+ ipc->return_info.win32_result =
+ LineBreakPolicy::GetComplexLineBreaksProxyAction(eval, text, length,
+ break_before);
+ return true;
+}
+
+} // namespace sandbox
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.h b/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.h
new file mode 100644
index 0000000000..774b5c5b56
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_dispatcher.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SANDBOX_SRC_LINE_BREAK_DISPATCHER_H_
+#define SANDBOX_SRC_LINE_BREAK_DISPATCHER_H_
+
+#include "base/macros.h"
+#include "sandbox/win/src/crosscall_server.h"
+#include "sandbox/win/src/sandbox_policy_base.h"
+
+namespace sandbox {
+
+// This class handles line break related IPC calls.
+class LineBreakDispatcher final : public Dispatcher {
+ public:
+ explicit LineBreakDispatcher(PolicyBase* policy_base);
+ ~LineBreakDispatcher() final {}
+
+ // Dispatcher interface.
+ bool SetupService(InterceptionManager* manager, IpcTag service) final;
+
+ private:
+ // Processes IPC requests coming from calls to
+ // TargetServices::GetComplexLineBreaks() in the target.
+ bool GetComplexLineBreaksCall(IPCInfo* ipc, CountedBuffer* text_buf,
+ uint32_t length,
+ CountedBuffer* break_before_buf);
+
+ PolicyBase* policy_base_;
+ DISALLOW_COPY_AND_ASSIGN(LineBreakDispatcher);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_LINE_BREAK_DISPATCHER_H_
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.cc b/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.cc
new file mode 100644
index 0000000000..f2dcda0dc9
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.cc
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "sandbox/win/src/line_break_interception.h"
+
+#include <winnls.h>
+
+#include "sandbox/win/src/crosscall_client.h"
+#include "sandbox/win/src/ipc_tags.h"
+#include "sandbox/win/src/line_break_common.h"
+#include "sandbox/win/src/sandbox_nt_util.h"
+#include "sandbox/win/src/sharedmem_ipc_client.h"
+
+namespace sandbox {
+
+static const int kBreakSearchRange = 32;
+
+ResultCode GetComplexLineBreaksProxy(const wchar_t* aText, uint32_t aLength,
+ uint8_t* aBreakBefore) {
+ // Make sure that a test length for kMaxBrokeredLen hasn't been set too small
+ // allowing for a surrogate pair at the end of a chunk as well.
+ DCHECK(kMaxBrokeredLen > kBreakSearchRange + 1);
+
+ void* memory = GetGlobalIPCMemory();
+ if (!memory) {
+ return SBOX_ERROR_NO_SPACE;
+ }
+
+ memset(aBreakBefore, false, aLength);
+
+ SharedMemIPCClient ipc(memory);
+
+ uint8_t* breakBeforeIter = aBreakBefore;
+ const wchar_t* textIterEnd = aText + aLength;
+ do {
+ // Next chunk is either the remaining text or kMaxBrokeredLen long.
+ const wchar_t* textIter = aText + (breakBeforeIter - aBreakBefore);
+ const wchar_t* chunkEnd = textIter + kMaxBrokeredLen;
+ if (chunkEnd < textIterEnd) {
+ // Make sure we don't split a surrogate pair.
+ if (IS_HIGH_SURROGATE(*(chunkEnd - 1))) {
+ --chunkEnd;
+ }
+ } else {
+ // This chunk handles all the (remaining) text.
+ chunkEnd = textIterEnd;
+ }
+
+ // Uniscribe seems to often (perhaps always) set the first element to a
+ // break, so we use chunk_start_reset to hold the known value of the first
+ // element of a chunk and reset it after Uniscribe processing. The only time
+ // we don't start from an already processed element is the first call, but
+ // resetting this to false is correct because whether we can break before
+ // the first character is decided by our caller.
+ uint8_t chunk_start_reset = *breakBeforeIter;
+
+ uint32_t len = chunkEnd - textIter;
+ // CountedBuffer takes a wchar_t* even though it doesn't change the buffer.
+ CountedBuffer textBuf(const_cast<wchar_t*>(textIter),
+ sizeof(wchar_t) * len);
+ InOutCountedBuffer breakBeforeBuf(breakBeforeIter, len);
+ CrossCallReturn answer = {0};
+ ResultCode code = CrossCall(ipc, IpcTag::GETCOMPLEXLINEBREAKS, textBuf, len,
+ breakBeforeBuf, &answer);
+ if (SBOX_ALL_OK != code) {
+ return code;
+ }
+
+ if (answer.win32_result) {
+ ::SetLastError(answer.win32_result);
+ return SBOX_ERROR_GENERIC;
+ }
+
+ *breakBeforeIter = chunk_start_reset;
+
+ if (chunkEnd == textIterEnd) {
+ break;
+ }
+
+ // We couldn't process all of the text in one go, so back up by 32 chars and
+ // look for a break, then continue from that position. We back up 32 chars
+ // to try to avoid any false breaks at the end of the buffer caused by us
+ // splitting it into chunks.
+ uint8_t* processedToEnd = breakBeforeIter + len;
+ breakBeforeIter = processedToEnd - kBreakSearchRange;
+ while (!*breakBeforeIter) {
+ if (++breakBeforeIter == processedToEnd) {
+ // We haven't found a break in the search range, so go back to the start
+ // of our search range to try and ensure we don't get any false breaks
+ // at the start of the new chunk.
+ breakBeforeIter = processedToEnd - kBreakSearchRange;
+ // Make sure we don't split a surrogate pair.
+ if (IS_LOW_SURROGATE(
+ *(aText + (breakBeforeIter - aBreakBefore)))) {
+ ++breakBeforeIter;
+ }
+ break;
+ }
+ }
+ } while (true);
+
+ return SBOX_ALL_OK;
+}
+
+} // namespace sandbox
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.h b/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.h
new file mode 100644
index 0000000000..87681e2e90
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_interception.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SANDBOX_SRC_LINE_BREAK_INTERCEPTION_H_
+#define SANDBOX_SRC_LINE_BREAK_INTERCEPTION_H_
+
+#include "sandbox/win/src/sandbox_types.h"
+
+namespace sandbox {
+
+ResultCode GetComplexLineBreaksProxy(const wchar_t* text, uint32_t length,
+ uint8_t* break_before);
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_LINE_BREAK_INTERCEPTION_H_
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.cc b/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.cc
new file mode 100644
index 0000000000..5533232643
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.cc
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "sandbox/win/src/line_break_policy.h"
+
+#include <algorithm>
+#include <array>
+#include <usp10.h>
+
+#include "sandbox/win/src/ipc_tags.h"
+#include "sandbox/win/src/line_break_common.h"
+#include "sandbox/win/src/policy_engine_opcodes.h"
+#include "sandbox/win/src/policy_params.h"
+
+namespace sandbox {
+
+bool LineBreakPolicy::GenerateRules(const wchar_t* null,
+ TargetPolicy::Semantics semantics,
+ LowLevelPolicy* policy) {
+ if (TargetPolicy::LINE_BREAK_ALLOW != semantics) {
+ return false;
+ }
+
+ PolicyRule line_break_rule(ASK_BROKER);
+ if (!policy->AddRule(IpcTag::GETCOMPLEXLINEBREAKS, &line_break_rule)) {
+ return false;
+ }
+ return true;
+}
+
+/* static */ DWORD LineBreakPolicy::GetComplexLineBreaksProxyAction(
+ EvalResult eval_result, const wchar_t* text, uint32_t length,
+ uint8_t* break_before) {
+ // The only action supported is ASK_BROKER which means call the line breaker.
+ if (ASK_BROKER != eval_result) {
+ return ERROR_ACCESS_DENIED;
+ }
+
+ int outItems = 0;
+ std::array<SCRIPT_ITEM, kMaxBrokeredLen + 1> items;
+ HRESULT result = ::ScriptItemize(text, length, kMaxBrokeredLen, nullptr,
+ nullptr, items.data(), &outItems);
+ if (result != 0) {
+ return ERROR_ACCESS_DENIED;
+ }
+
+ std::array<SCRIPT_LOGATTR, kMaxBrokeredLen> slas;
+ for (int iItem = 0; iItem < outItems; ++iItem) {
+ uint32_t endOffset = items[iItem + 1].iCharPos;
+ uint32_t startOffset = items[iItem].iCharPos;
+ if (FAILED(::ScriptBreak(text + startOffset, endOffset - startOffset,
+ &items[iItem].a, &slas[startOffset]))) {
+ return ERROR_ACCESS_DENIED;
+ }
+ }
+
+ std::transform(slas.data(), slas.data() + length, break_before,
+ [](const SCRIPT_LOGATTR& sla) { return sla.fSoftBreak; });
+
+ return ERROR_SUCCESS;
+}
+
+} // namespace sandbox
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.h b/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.h
new file mode 100644
index 0000000000..89fbf9b207
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/line_break_policy.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SANDBOX_SRC_LINE_BREAK_POLICY_H_
+#define SANDBOX_SRC_LINE_BREAK_POLICY_H_
+
+#include "base/win/windows_types.h"
+#include "sandbox/win/src/policy_low_level.h"
+#include "sandbox/win/src/sandbox_policy.h"
+
+namespace sandbox {
+
+enum EvalResult;
+
+class LineBreakPolicy {
+ public:
+ // Creates the required low-level policy rules to evaluate a high-level
+ // policy rule for complex line breaks.
+ static bool GenerateRules(const wchar_t* type_name,
+ TargetPolicy::Semantics semantics,
+ LowLevelPolicy* policy);
+
+ // Processes a TargetServices::GetComplexLineBreaks() request from the target.
+ static DWORD GetComplexLineBreaksProxyAction(EvalResult eval_result,
+ const wchar_t* text,
+ uint32_t length,
+ uint8_t* break_before);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_LINE_BREAK_POLICY_H_
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/sandbox_policy_diagnostic.h b/security/sandbox/chromium-shim/sandbox/win/src/sandbox_policy_diagnostic.h
new file mode 100644
index 0000000000..5b37ccc556
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/sandbox_policy_diagnostic.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This is a partial implementation of Chromium's source file
+// //sandbox/win/src/sandbox_policy_diagnostic.h
+
+#ifndef SANDBOX_WIN_SRC_SANDBOX_POLICY_DIAGNOSTIC_H_
+#define SANDBOX_WIN_SRC_SANDBOX_POLICY_DIAGNOSTIC_H_
+
+#include "mozilla/Assertions.h"
+
+namespace sandbox {
+
+class PolicyBase;
+
+class PolicyDiagnostic final : public PolicyInfo {
+ public:
+ PolicyDiagnostic(PolicyBase*) {}
+ ~PolicyDiagnostic() override = default;
+ const char* JsonString() override { MOZ_CRASH(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PolicyDiagnostic);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_WIN_SRC_SANDBOX_POLICY_DIAGNOSTIC_H_
diff --git a/security/sandbox/chromium-shim/sandbox/win/src/sidestep_resolver.h b/security/sandbox/chromium-shim/sandbox/win/src/sidestep_resolver.h
new file mode 100644
index 0000000000..fe38484b0e
--- /dev/null
+++ b/security/sandbox/chromium-shim/sandbox/win/src/sidestep_resolver.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+// This is a dummy version of the Chromium source file
+// sandbox/win/src/sidestep_resolver.h, which contains classes that are never
+// actually used. We crash in the member functions to ensure this.
+// Formatting and guards closely match original file for easy comparison.
+
+#ifndef SANDBOX_SRC_SIDESTEP_RESOLVER_H__
+#define SANDBOX_SRC_SIDESTEP_RESOLVER_H__
+
+#include <stddef.h>
+
+#include "base/macros.h"
+#include "sandbox/win/src/nt_internals.h"
+#include "sandbox/win/src/resolver.h"
+
+#include "mozilla/Assertions.h"
+
+namespace sandbox {
+
+class SidestepResolverThunk : public ResolverThunk {
+ public:
+ SidestepResolverThunk() {}
+ ~SidestepResolverThunk() override {}
+
+ // Implementation of Resolver::Setup.
+ NTSTATUS Setup(const void* target_module,
+ const void* interceptor_module,
+ const char* target_name,
+ const char* interceptor_name,
+ const void* interceptor_entry_point,
+ void* thunk_storage,
+ size_t storage_bytes,
+ size_t* storage_used) override { MOZ_CRASH(); }
+
+ size_t GetThunkSize() const override { MOZ_CRASH(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SidestepResolverThunk);
+};
+
+class SmartSidestepResolverThunk : public SidestepResolverThunk {
+ public:
+ SmartSidestepResolverThunk() {}
+ ~SmartSidestepResolverThunk() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SmartSidestepResolverThunk);
+};
+
+} // namespace sandbox
+
+
+#endif // SANDBOX_SRC_SIDESTEP_RESOLVER_H__