summaryrefslogtreecommitdiffstats
path: root/sandbox/src/named_pipe_policy.cc
blob: c08c00ae0cc1961b6cf7bed979f02a52122c467c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright (c) 2006-2008 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/src/named_pipe_policy.h"

#include <string>

#include "base/scoped_ptr.h"
#include "sandbox/src/ipc_tags.h"
#include "sandbox/src/policy_engine_opcodes.h"
#include "sandbox/src/policy_params.h"
#include "sandbox/src/sandbox_types.h"

namespace {

// Creates a named pipe and duplicates the handle to 'target_process'. The
// remaining parameters are the same as CreateNamedPipeW().
HANDLE CreateNamedPipeHelper(HANDLE target_process, LPCWSTR pipe_name,
                              DWORD open_mode, DWORD pipe_mode,
                              DWORD max_instances, DWORD out_buffer_size,
                              DWORD in_buffer_size, DWORD default_timeout,
                              LPSECURITY_ATTRIBUTES security_attributes) {
  HANDLE pipe = ::CreateNamedPipeW(pipe_name, open_mode, pipe_mode,
                                   max_instances, out_buffer_size,
                                   in_buffer_size, default_timeout,
                                   security_attributes);
  if (INVALID_HANDLE_VALUE == pipe)
    return pipe;

  HANDLE new_pipe;
  if (!::DuplicateHandle(::GetCurrentProcess(), pipe, target_process, &new_pipe,
                         0, FALSE, DUPLICATE_CLOSE_SOURCE |
                             DUPLICATE_SAME_ACCESS)) {
    ::CloseHandle(pipe);
    return INVALID_HANDLE_VALUE;
  }

  return new_pipe;
}

}  // namespace

namespace sandbox {

bool NamedPipePolicy::GenerateRules(const wchar_t* name,
                                    TargetPolicy::Semantics semantics,
                                    LowLevelPolicy* policy) {
  if (TargetPolicy::NAMEDPIPES_ALLOW_ANY != semantics) {
    return false;
  }
  PolicyRule pipe(ASK_BROKER);
  if (!pipe.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) {
    return false;
  }
  if (!policy->AddRule(IPC_CREATENAMEDPIPEW_TAG, &pipe)) {
    return false;
  }
  return true;
}

DWORD NamedPipePolicy::CreateNamedPipeAction(EvalResult eval_result,
                                             const ClientInfo& client_info,
                                             const std::wstring &name,
                                             DWORD open_mode, DWORD pipe_mode,
                                             DWORD max_instances,
                                             DWORD out_buffer_size,
                                             DWORD in_buffer_size,
                                             DWORD default_timeout,
                                             HANDLE* pipe) {
  // The only action supported is ASK_BROKER which means create the pipe.
  if (ASK_BROKER != eval_result) {
    return ERROR_ACCESS_DENIED;
  }

  *pipe = CreateNamedPipeHelper(client_info.process, name.c_str(),
                                open_mode, pipe_mode, max_instances,
                                out_buffer_size, in_buffer_size,
                                default_timeout, NULL);

  if (INVALID_HANDLE_VALUE == *pipe)
    return ERROR_ACCESS_DENIED;

  return ERROR_SUCCESS;
}

}  // namespace sandbox