| Index: sandbox/win/src/named_pipe_dispatcher.cc
|
| ===================================================================
|
| --- sandbox/win/src/named_pipe_dispatcher.cc (revision 248756)
|
| +++ sandbox/win/src/named_pipe_dispatcher.cc (working copy)
|
| @@ -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 @@
|
| 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 @@
|
| 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,
|
|
|