blob: aa55a5e3f58bd3d58f538539a9ef2343fffca066 [file] [log] [blame]
Elly Jonesa44d22d2012-01-05 18:05:56 -05001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Elly Jones9aa5eca2011-11-04 14:48:13 -04002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Elly Jones9aa5eca2011-11-04 14:48:13 -04005#include <sys/mount.h>
Elly Jonesd31aee22012-07-02 11:09:10 -04006#include <sys/stat.h>
Elly Jones9aa5eca2011-11-04 14:48:13 -04007#include <unistd.h>
8
Elly Jonese7cb5b32011-12-01 14:18:32 -05009#include <base/command_line.h>
10#include <base/logging.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070011#include <brillo/daemons/dbus_daemon.h>
Mike Frysinger0597cdd2020-03-18 05:32:21 -040012#include <brillo/flag_helper.h>
Alex Vakulenkoe7696532015-10-16 16:27:29 -070013#include <brillo/syslog_logging.h>
Eric Carusocc7106c2017-04-27 14:22:42 -070014#include <chromeos/dbus/service_constants.h>
Elly Jones9aa5eca2011-11-04 14:48:13 -040015#include <chromeos/libminijail.h>
Luis Hector Chavezce837b82018-05-09 18:08:38 -070016#include <chromeos/scoped_minijail.h>
Elly Jones9aa5eca2011-11-04 14:48:13 -040017
Eric Caruso63c97432017-04-27 13:23:28 -070018#include "debugd/src/debugd_dbus_adaptor.h"
Elly Jones9aa5eca2011-11-04 14:48:13 -040019
Elly Jonese7cb5b32011-12-01 14:18:32 -050020namespace {
Elly Jones9aa5eca2011-11-04 14:48:13 -040021
Andrey Pronin0f029d82018-07-11 15:25:26 -070022// For TPM 1.2 only: Directory to mount for access to tcsd socket.
23constexpr char kTcsdDir[] = "/run/tcsd";
Nicole Anderson-Aud2b90982021-02-26 18:36:34 +000024// The directory of the daemonstore mount.
25constexpr char daemonstore[] = "/run/daemon-store/debugd";
Andrey Pronin0f029d82018-07-11 15:25:26 -070026
Elly Jonese7cb5b32011-12-01 14:18:32 -050027// @brief Enter a VFS namespace.
28//
29// We don't want anyone other than our descendants to see our tmpfs.
30void enter_vfs_namespace() {
Luis Hector Chavezce837b82018-05-09 18:08:38 -070031 ScopedMinijail j(minijail_new());
32
33 // Create a minimalistic mount namespace with just the bare minimum required.
34 minijail_namespace_vfs(j.get());
Allen Webb2b6e35d2019-02-21 10:06:31 -080035 if (minijail_enter_pivot_root(j.get(), "/mnt/empty"))
Luis Hector Chavezce837b82018-05-09 18:08:38 -070036 LOG(FATAL) << "minijail_enter_pivot_root() failed";
37 if (minijail_bind(j.get(), "/", "/", 0))
38 LOG(FATAL) << "minijail_bind(\"/\") failed";
39 if (minijail_mount_with_data(j.get(), "none", "/proc", "proc",
40 MS_NOSUID | MS_NOEXEC | MS_NODEV, nullptr)) {
41 LOG(FATAL) << "minijail_mount_with_data(\"/proc\") failed";
42 }
43 if (minijail_bind(j.get(), "/var", "/var", 1))
44 LOG(FATAL) << "minijail_bind(\"/var\") failed";
45
Mike Frysinger25cdbe72018-08-23 01:54:00 -040046 // Hack a path for vpd until it can migrate to /var.
47 // https://crbug.com/876838
48 if (minijail_mount_with_data(j.get(), "tmpfs", "/mnt", "tmpfs",
49 MS_NOSUID | MS_NOEXEC | MS_NODEV,
50 "mode=0755,size=10M")) {
51 LOG(FATAL) << "minijail_mount_with_data(\"/mnt\") failed";
52 }
53 const char kVpdPath[] = "/mnt/stateful_partition/unencrypted/cache/vpd";
54 if (minijail_bind(j.get(), kVpdPath, kVpdPath, 1))
55 LOG(FATAL) << "minijail_bind(\"" << kVpdPath << "\") failed";
56
Nicole Anderson-Aud2b90982021-02-26 18:36:34 +000057 minijail_remount_mode(j.get(), MS_PRIVATE);
mhasank545ccff2020-04-01 12:10:54 -070058
Luis Hector Chavezce837b82018-05-09 18:08:38 -070059 if (minijail_mount_with_data(j.get(), "tmpfs", "/run", "tmpfs",
60 MS_NOSUID | MS_NOEXEC | MS_NODEV, nullptr)) {
61 LOG(FATAL) << "minijail_mount_with_data(\"/run\") failed";
62 }
mhasank545ccff2020-04-01 12:10:54 -070063
Nicole Anderson-Aud2b90982021-02-26 18:36:34 +000064 minijail_add_remount(j.get(), daemonstore, MS_SLAVE);
65
66 if (minijail_mount(j.get(), daemonstore, daemonstore, "none",
mhasank545ccff2020-04-01 12:10:54 -070067 MS_BIND | MS_REC) != 0) {
Nicole Anderson-Aud2b90982021-02-26 18:36:34 +000068 LOG(FATAL) << "minijail_mount(\"" << daemonstore << "\") failed";
mhasank545ccff2020-04-01 12:10:54 -070069 }
70
71 // Mount /run/dbus to be able to communicate with D-Bus.
Luis Hector Chavezce837b82018-05-09 18:08:38 -070072 if (minijail_bind(j.get(), "/run/dbus", "/run/dbus", 0))
73 LOG(FATAL) << "minijail_bind(\"/run/dbus\") failed";
74
David Valleaue694deb2018-07-30 17:19:11 -070075 // Mount /tmp, /run/cups, and /run/ippusb to be able to communicate with CUPS.
Piotr Pawliczek39752f32018-10-16 14:42:28 -070076 minijail_mount_tmp(j.get());
Mike Frysinger97000d82018-06-05 11:36:12 -040077 // In case we start before cups, make sure the path exists.
78 mkdir("/run/cups", 0755);
Luis Hector Chavezce837b82018-05-09 18:08:38 -070079 if (minijail_bind(j.get(), "/run/cups", "/run/cups", 0))
80 LOG(FATAL) << "minijail_bind(\"/run/cups\") failed";
David Valleaue694deb2018-07-30 17:19:11 -070081 // In case we start before upstart-socket-bridge, make sure the path exists.
82 mkdir("/run/ippusb", 0755);
83 // Mount /run/ippusb to be able to communicate with CUPS.
84 if (minijail_bind(j.get(), "/run/ippusb", "/run/ippusb", 0))
85 LOG(FATAL) << "minijail_bind(\"/run/ippusb\") failed";
Luis Hector Chavezce837b82018-05-09 18:08:38 -070086
David Valleau3339ca22019-03-19 13:33:24 -070087 // In case we start before avahi-daemon, make sure the path exists.
88 mkdir("/var/run/avahi-daemon", 0755);
89 // Mount /run/avahi-daemon in order to perform mdns name resolution.
Tom Hughesd6c2d392020-08-24 18:12:11 -070090 if (minijail_bind(j.get(), "/run/avahi-daemon", "/run/avahi-daemon", 0))
David Valleau3339ca22019-03-19 13:33:24 -070091 LOG(FATAL) << "minijail_bind(\"/run/avahi-daemon\") failed";
92
Mike Frysinger65884e62018-07-09 13:41:26 -040093 // Since shill provides network resolution settings, bind mount it.
94 // In case we start before shill, make sure the path exists.
95 mkdir("/run/shill", 0755);
96 if (minijail_bind(j.get(), "/run/shill", "/run/shill", 0))
97 LOG(FATAL) << "minijail_bind(\"/run/shill\") failed";
98
Chris Morinb7a32eb2019-02-19 20:06:21 -080099 // Mount /run/systemd/journal to be able to log to journald.
Chris Morinb7a32eb2019-02-19 20:06:21 -0800100 if (minijail_bind(j.get(), "/run/systemd/journal", "/run/systemd/journal", 0))
101 LOG(FATAL) << "minijail_bind(\"/run/systemd/journal\") failed";
102
Luis Hector Chavezce837b82018-05-09 18:08:38 -0700103 // Mount /dev to be able to inspect devices.
104 if (minijail_mount_with_data(j.get(), "/dev", "/dev", "bind",
105 MS_BIND | MS_REC, nullptr)) {
106 LOG(FATAL) << "minijail_mount_with_data(\"/dev\") failed";
107 }
108
109 // Mount /sys to access some logs.
110 if (minijail_mount_with_data(j.get(), "/sys", "/sys", "bind",
111 MS_BIND | MS_REC, nullptr)) {
112 LOG(FATAL) << "minijail_mount_with_data(\"/sys\") failed";
113 }
114
Jesse Schettlere1277642020-02-27 12:23:18 -0700115 // Mount /run/chromeos-config/v1 to access chromeos-config.
116 if (minijail_bind(j.get(), "/run/chromeos-config/v1",
117 "/run/chromeos-config/v1", 0)) {
118 LOG(FATAL) << "minijail_bind(\"/run/chromeos-config/v1\") failed";
119 }
120
Andrey Pronin0f029d82018-07-11 15:25:26 -0700121 if (USE_TPM) {
122 // For TPM 1.2 only: Enable utilities that communicate with TPM via tcsd -
123 // mount directory containing tcsd socket.
124 mkdir(kTcsdDir, 0755);
125 if (minijail_bind(j.get(), kTcsdDir, kTcsdDir, 0)) {
126 LOG(FATAL) << "minijail_bind(\"" << kTcsdDir << "\") failed";
127 }
128 }
129
Luis Hector Chavezce837b82018-05-09 18:08:38 -0700130 minijail_enter(j.get());
Elly Jones9aa5eca2011-11-04 14:48:13 -0400131}
132
Eric Carusocc7106c2017-04-27 14:22:42 -0700133class Daemon : public brillo::DBusServiceDaemon {
134 public:
Eric Caruso51535852017-07-11 14:13:20 -0700135 Daemon() : DBusServiceDaemon(debugd::kDebugdServiceName) {}
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900136 Daemon(const Daemon&) = delete;
137 Daemon& operator=(const Daemon&) = delete;
Eric Carusocc7106c2017-04-27 14:22:42 -0700138
139 protected:
140 void RegisterDBusObjectsAsync(
Eric Carusob298bb42017-05-09 10:53:30 -0700141 brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
Eric Caruso51535852017-07-11 14:13:20 -0700142 adaptor_.reset(new debugd::DebugdDBusAdaptor(bus_));
Tom Hughesd6c2d392020-08-24 18:12:11 -0700143 adaptor_->RegisterAsync(
144 sequencer->GetHandler("RegisterAsync() failed.", true));
Eric Carusocc7106c2017-04-27 14:22:42 -0700145 }
146
147 private:
148 std::unique_ptr<debugd::DebugdDBusAdaptor> adaptor_;
Eric Carusocc7106c2017-04-27 14:22:42 -0700149};
Ben Chanaf125862017-02-08 23:11:18 -0800150
151} // namespace
Elly Jones9aa5eca2011-11-04 14:48:13 -0400152
Ben Chanc572aff2018-04-10 09:20:27 -0700153int main(int argc, char* argv[]) {
Mike Frysinger0597cdd2020-03-18 05:32:21 -0400154 brillo::FlagHelper::Init(argc, argv, "CrOS debug daemon");
Mike Frysingerb2f7ac52018-05-17 02:36:23 -0400155 brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
Mike Frysinger0597cdd2020-03-18 05:32:21 -0400156 if (argc != 1) {
157 LOG(ERROR) << "debugd takes no arguments";
158 return 1;
159 }
160
Elly Jonese7cb5b32011-12-01 14:18:32 -0500161 enter_vfs_namespace();
Eric Carusocc7106c2017-04-27 14:22:42 -0700162 Daemon().Run();
Elly Jones9aa5eca2011-11-04 14:48:13 -0400163 return 0;
164}