# HG changeset patch
# User Toshihito Kikuchi <tkikuchi@mozilla.com>
# Date 1605814807 28800
#      Thu Nov 19 11:40:07 2020 -0800
# Node ID 29b049665db1f28ffdfce319ad48912d4a024e23
# Parent  94435953fb89c1fe147c6b76a9ecb61f59625d30
Bug 1620114 - Allow an NT path string to be passed to SignedPolicy::GenerateRules.  r=bobowen
so that our SandboxBroker can add a policy rule with an NT path directly.

diff --git a/sandbox/win/src/signed_policy.cc b/sandbox/win/src/signed_policy.cc
--- a/sandbox/win/src/signed_policy.cc
+++ b/sandbox/win/src/signed_policy.cc
@@ -11,37 +11,60 @@

 #include "base/containers/contains.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_engine_opcodes.h"
 #include "sandbox/win/src/policy_params.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sandbox_policy.h"
 #include "sandbox/win/src/win_utils.h"
+
+namespace {
+bool IsValidNtPath(const base::FilePath& name) {
+  UNICODE_STRING uni_name;
+  ::RtlInitUnicodeString(&uni_name, name.value().c_str());
+  OBJECT_ATTRIBUTES obj_attr;
+  InitializeObjectAttributes(&obj_attr, &uni_name, OBJ_CASE_INSENSITIVE,
+                             nullptr, nullptr);
+
+  static const auto NtQueryAttributesFile =
+      reinterpret_cast<NtQueryAttributesFileFunction>(::GetProcAddress(
+          ::GetModuleHandleW(L"ntdll.dll"), "NtQueryAttributesFile"));
+
+  FILE_BASIC_INFORMATION file_info;
+  return NtQueryAttributesFile &&
+         NT_SUCCESS(NtQueryAttributesFile(&obj_attr, &file_info));
+}
+}  // namespace
 
 namespace sandbox {
 
 bool SignedPolicy::GenerateRules(base::FilePath dll_path,
                                  LowLevelPolicy* policy) {
   // Disallow patterns to allow for future API changes.
   if (base::Contains(dll_path.value(), L'*')) {
     return false;
   }
   if (!dll_path.IsAbsolute()) {
     return false;
   }
 
   auto nt_path_name = GetNtPathFromWin32Path(dll_path.DirName().value());
-  if (!nt_path_name) {
+  base::FilePath nt_filename;
+  if (nt_path_name) {
+    base::FilePath nt_path(nt_path_name.value());
+    nt_filename = nt_path.Append(dll_path.BaseName());
+  } else if (IsValidNtPath(dll_path)) {
+    nt_filename = dll_path;
+  } else {
     return false;
   }
 
-  base::FilePath nt_path(nt_path_name.value());
-  std::wstring nt_filename = nt_path.Append(dll_path.BaseName()).value();
   // Create a rule to ASK_BROKER if name matches.
   PolicyRule signed_policy(ASK_BROKER);
-  if (!signed_policy.AddStringMatch(IF, NameBased::NAME, nt_filename.c_str())) {
+  if (!signed_policy.AddStringMatch(IF, NameBased::NAME,
+                                    nt_filename.value().c_str())) {
     return false;
   }
   if (!policy->AddRule(IpcTag::NTCREATESECTION, &signed_policy)) {
     return false;
   }
 
   return true;
 }
