Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 1 | // Copyright 2016 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Hidehiko Abe | 3a7e513 | 2018-02-15 13:07:50 +0900 | [diff] [blame] | 5 | #include "arc/network/manager.h" |
Kevin Cernekee | 4e62cc1 | 2016-12-03 11:50:53 -0800 | [diff] [blame] | 6 | |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 7 | #include <arpa/inet.h> |
Hugo Benichi | 935eca9 | 2018-07-03 13:47:24 +0900 | [diff] [blame] | 8 | #include <netinet/in.h> |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 9 | #include <stdint.h> |
| 10 | |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 11 | #include <utility> |
| 12 | |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 13 | #include <base/bind.h> |
| 14 | #include <base/logging.h> |
| 15 | #include <base/message_loop/message_loop.h> |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 16 | #include <base/strings/stringprintf.h> |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 17 | #include <brillo/minijail/minijail.h> |
| 18 | |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 19 | #include "arc/network/ipc.pb.h" |
| 20 | |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 21 | namespace { |
| 22 | |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 23 | const uint64_t kManagerCapMask = CAP_TO_MASK(CAP_NET_RAW); |
Garrick Evans | d2bb850 | 2019-02-20 15:59:35 +0900 | [diff] [blame] | 24 | const char kUnprivilegedUser[] = "arc-networkd"; |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 25 | |
| 26 | } // namespace |
| 27 | |
| 28 | namespace arc_networkd { |
| 29 | |
Garrick Evans | d2bb850 | 2019-02-20 15:59:35 +0900 | [diff] [blame] | 30 | Manager::Manager(std::unique_ptr<HelperProcess> ip_helper, bool enable_multinet) |
Garrick Evans | f4a9329 | 2019-03-13 14:19:43 +0900 | [diff] [blame] | 31 | : addr_mgr_({ |
| 32 | AddressManager::Guest::ARC, |
| 33 | AddressManager::Guest::ARC_NET, |
| 34 | }), |
| 35 | enable_multinet_(enable_multinet) { |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 36 | ip_helper_ = std::move(ip_helper); |
| 37 | } |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 38 | |
| 39 | int Manager::OnInit() { |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 40 | // Run with minimal privileges. |
| 41 | brillo::Minijail* m = brillo::Minijail::GetInstance(); |
| 42 | struct minijail* jail = m->New(); |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 43 | |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 44 | // Most of these return void, but DropRoot() can fail if the user/group |
| 45 | // does not exist. |
Hugo Benichi | 935eca9 | 2018-07-03 13:47:24 +0900 | [diff] [blame] | 46 | CHECK(m->DropRoot(jail, kUnprivilegedUser, kUnprivilegedUser)) |
| 47 | << "Could not drop root privileges"; |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 48 | m->UseCapabilities(jail, kManagerCapMask); |
| 49 | m->Enter(jail); |
| 50 | m->Destroy(jail); |
| 51 | |
| 52 | // Handle subprocess lifecycle. |
| 53 | process_reaper_.Register(this); |
Hugo Benichi | 935eca9 | 2018-07-03 13:47:24 +0900 | [diff] [blame] | 54 | |
| 55 | CHECK(process_reaper_.WatchForChild( |
Hidehiko Abe | 3a7e513 | 2018-02-15 13:07:50 +0900 | [diff] [blame] | 56 | FROM_HERE, ip_helper_->pid(), |
| 57 | base::Bind(&Manager::OnSubprocessExited, weak_factory_.GetWeakPtr(), |
Hugo Benichi | 935eca9 | 2018-07-03 13:47:24 +0900 | [diff] [blame] | 58 | ip_helper_->pid()))) |
| 59 | << "Failed to watch child IpHelper process"; |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 60 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 61 | // Handle container lifecycle. |
| 62 | RegisterHandler( |
| 63 | SIGUSR1, base::Bind(&Manager::OnContainerStart, base::Unretained(this))); |
| 64 | RegisterHandler( |
| 65 | SIGUSR2, base::Bind(&Manager::OnContainerStop, base::Unretained(this))); |
| 66 | |
| 67 | // Run after Daemon::OnInit(). |
Eric Caruso | 9ce5418 | 2018-01-04 11:19:47 -0800 | [diff] [blame] | 68 | base::MessageLoopForIO::current()->task_runner()->PostTask( |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 69 | FROM_HERE, |
| 70 | base::Bind(&Manager::InitialSetup, weak_factory_.GetWeakPtr())); |
| 71 | |
| 72 | return DBusDaemon::OnInit(); |
| 73 | } |
| 74 | |
| 75 | void Manager::InitialSetup() { |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 76 | device_mgr_ = std::make_unique<DeviceManager>( |
Garrick Evans | ef6b20d | 2019-05-31 13:29:24 +0900 | [diff] [blame^] | 77 | std::make_unique<ShillClient>(std::move(bus_)), &addr_mgr_, |
| 78 | base::Bind(&Manager::SendMessage, weak_factory_.GetWeakPtr()), |
| 79 | !enable_multinet_); |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 80 | } |
| 81 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 82 | bool Manager::OnContainerStart(const struct signalfd_siginfo& info) { |
| 83 | if (info.ssi_code == SI_USER) { |
Garrick Evans | ef6b20d | 2019-05-31 13:29:24 +0900 | [diff] [blame^] | 84 | device_mgr_->OnGuestStart(); |
Hugo Benichi | ee787ff | 2019-05-20 16:42:42 +0900 | [diff] [blame] | 85 | } |
| 86 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 87 | // Stay registered. |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | bool Manager::OnContainerStop(const struct signalfd_siginfo& info) { |
| 92 | if (info.ssi_code == SI_USER) { |
Garrick Evans | ef6b20d | 2019-05-31 13:29:24 +0900 | [diff] [blame^] | 93 | device_mgr_->OnGuestStop(); |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | // Stay registered. |
| 97 | return false; |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 98 | } |
| 99 | |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 100 | void Manager::OnShutdown(int* exit_code) { |
Garrick Evans | 428e476 | 2018-12-11 15:18:42 +0900 | [diff] [blame] | 101 | device_mgr_.reset(); |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | void Manager::OnSubprocessExited(pid_t pid, const siginfo_t& info) { |
Hugo Benichi | 10a2af4 | 2018-08-27 10:09:42 +0900 | [diff] [blame] | 105 | LOG(ERROR) << "Subprocess " << pid << " exited unexpectedly"; |
| 106 | Quit(); |
Kevin Cernekee | 27bcaa6 | 2016-12-03 11:16:26 -0800 | [diff] [blame] | 107 | } |
| 108 | |
Garrick Evans | 4987953 | 2018-12-03 13:15:36 +0900 | [diff] [blame] | 109 | void Manager::SendMessage(const IpHelperMessage& msg) { |
| 110 | ip_helper_->SendMessage(msg); |
Hugo Benichi | 935eca9 | 2018-07-03 13:47:24 +0900 | [diff] [blame] | 111 | } |
| 112 | |
Kevin Cernekee | 95d4ae9 | 2016-06-19 10:26:29 -0700 | [diff] [blame] | 113 | } // namespace arc_networkd |