1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/nacl/loader/nacl_trusted_listener.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/functional/bind.h"
11 #include "base/task/single_thread_task_runner.h"
12 #include "build/build_config.h"
13 #include "mojo/public/cpp/bindings/pending_receiver.h"
14 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
15 #include "native_client/src/public/chrome_main.h"
16
17 namespace {
18
19 #if defined(COMPILER_MSVC)
20 // Disable warning that we don't care about:
21 // warning C4722: destructor never returns, potential memory leak
22 #pragma warning(disable : 4722)
23 #endif
24
25 class NaClExitControlImpl : public nacl::mojom::NaClExitControl {
26 public:
~NaClExitControlImpl()27 ~NaClExitControlImpl() override {
28 // If the binding disconnects, the renderer process dropped its connection
29 // to this process (the NaCl loader process), either because the <embed>
30 // element was removed (perhaps implicitly if the tab was closed) or because
31 // the renderer crashed. The NaCl loader process should therefore exit.
32 //
33 // Trusted code does this exit voluntarily, but untrusted code cannot
34 // disable it.
35 NaClExit(0);
36 }
37 };
38
CreateExitControl(mojo::PendingReceiver<nacl::mojom::NaClExitControl> receiver)39 void CreateExitControl(
40 mojo::PendingReceiver<nacl::mojom::NaClExitControl> receiver) {
41 mojo::MakeSelfOwnedReceiver(std::make_unique<NaClExitControlImpl>(),
42 std::move(receiver));
43 }
44
45 } // namespace
46
NaClTrustedListener(mojo::PendingRemote<nacl::mojom::NaClRendererHost> renderer_host,base::SingleThreadTaskRunner * io_task_runner)47 NaClTrustedListener::NaClTrustedListener(
48 mojo::PendingRemote<nacl::mojom::NaClRendererHost> renderer_host,
49 base::SingleThreadTaskRunner* io_task_runner)
50 : renderer_host_(std::move(renderer_host)) {
51 mojo::PendingRemote<nacl::mojom::NaClExitControl> exit_control;
52 // The exit control binding must run on the IO thread. The main thread used
53 // by NaClListener is busy in NaClChromeMainAppStart(), so it can't be used
54 // for servicing messages.
55 io_task_runner->PostTask(
56 FROM_HERE, base::BindOnce(&CreateExitControl,
57 exit_control.InitWithNewPipeAndPassReceiver()));
58 renderer_host_->ProvideExitControl(std::move(exit_control));
59 }
60
61 NaClTrustedListener::~NaClTrustedListener() = default;
62