Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / sandbox / win / src / named_pipe_dispatcher.cc
index 54b3162..daf88f8 100644 (file)
@@ -5,6 +5,7 @@
 #include "sandbox/win/src/named_pipe_dispatcher.h"
 
 #include "base/basictypes.h"
+#include "base/strings/string_split.h"
 
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/interception.h"
@@ -43,6 +44,23 @@ bool NamedPipeDispatcher::CreateNamedPipe(
     IPCInfo* ipc, base::string16* name, DWORD open_mode, DWORD pipe_mode,
     DWORD max_instances, DWORD out_buffer_size, DWORD in_buffer_size,
     DWORD default_timeout) {
+  ipc->return_info.win32_result = ERROR_ACCESS_DENIED;
+  ipc->return_info.handle = INVALID_HANDLE_VALUE;
+
+  std::vector<base::string16> paths;
+  std::vector<base::string16> innerpaths;
+  base::SplitString(*name, '/', &paths);
+
+  for (std::vector<base::string16>::const_iterator iter = paths.begin();
+       iter != paths.end(); ++iter) {
+    base::SplitString(*iter, '\\', &innerpaths);
+    for (std::vector<base::string16>::const_iterator iter2 = innerpaths.begin();
+         iter2 != innerpaths.end(); ++iter2) {
+      if (*iter2 == L"..")
+        return true;
+    }
+  }
+
   const wchar_t* pipe_name = name->c_str();
   CountedParameterSet<NameBased> params;
   params[NameBased::NAME] = ParamPickerMake(pipe_name);
@@ -50,6 +68,16 @@ bool NamedPipeDispatcher::CreateNamedPipe(
   EvalResult eval = policy_base_->EvalPolicy(IPC_CREATENAMEDPIPEW_TAG,
                                              params.GetBase());
 
+  // "For file I/O, the "\\?\" prefix to a path string tells the Windows APIs to
+  // disable all string parsing and to send the string that follows it straight
+  // to the file system."
+  // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx
+  // This ensures even if there is a path traversal in the pipe name, and it is
+  // able to get past the checks above, it will still not be allowed to escape
+  // our whitelisted namespace.
+  if (name->compare(0, 4, L"\\\\.\\") == 0)
+    name->replace(0, 4, L"\\\\\?\\");
+
   HANDLE pipe;
   DWORD ret = NamedPipePolicy::CreateNamedPipeAction(eval, *ipc->client_info,
                                                      *name, open_mode,