• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <sysexits.h>
18 
19 #include <base/at_exit.h>
20 #include <base/bind.h>
21 #include <base/command_line.h>
22 #include <base/threading/thread.h>
23 #include <brillo/minijail/minijail.h>
24 #include <brillo/syslog_logging.h>
25 #include <brillo/userdb_utils.h>
26 
27 #include "trunks/background_command_transceiver.h"
28 #include "trunks/resource_manager.h"
29 #include "trunks/tpm_handle.h"
30 #include "trunks/tpm_simulator_handle.h"
31 #if defined(USE_BINDER_IPC)
32 #include "trunks/trunks_binder_service.h"
33 #else
34 #include "trunks/trunks_dbus_service.h"
35 #endif
36 #include "trunks/trunks_factory_impl.h"
37 #include "trunks/trunks_ftdi_spi.h"
38 
39 namespace {
40 
41 const uid_t kRootUID = 0;
42 #if defined(__ANDROID__)
43 const char kTrunksUser[] = "system";
44 const char kTrunksGroup[] = "system";
45 const char kTrunksSeccompPath[] =
46     "/system/usr/share/policy/trunksd-seccomp.policy";
47 #else
48 const char kTrunksUser[] = "trunks";
49 const char kTrunksGroup[] = "trunks";
50 const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
51 #endif
52 const char kBackgroundThreadName[] = "trunksd_background_thread";
53 
InitMinijailSandbox()54 void InitMinijailSandbox() {
55   uid_t trunks_uid;
56   gid_t trunks_gid;
57   CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
58       << "Error getting trunks uid and gid.";
59   CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root.";
60   brillo::Minijail* minijail = brillo::Minijail::GetInstance();
61   struct minijail* jail = minijail->New();
62   minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
63   minijail->UseSeccompFilter(jail, kTrunksSeccompPath);
64   minijail->Enter(jail);
65   minijail->Destroy(jail);
66   CHECK_EQ(getuid(), trunks_uid)
67       << "trunksd was not able to drop user privilege.";
68   CHECK_EQ(getgid(), trunks_gid)
69       << "trunksd was not able to drop group privilege.";
70 }
71 
72 }  // namespace
73 
main(int argc,char ** argv)74 int main(int argc, char **argv) {
75   base::CommandLine::Init(argc, argv);
76   base::CommandLine *cl = base::CommandLine::ForCurrentProcess();
77   int flags = brillo::kLogToSyslog;
78   if (cl->HasSwitch("log_to_stderr")) {
79     flags |= brillo::kLogToStderr;
80   }
81   brillo::InitLog(flags);
82 
83   // Create a service instance before anything else so objects like
84   // AtExitManager exist.
85 #if defined(USE_BINDER_IPC)
86   trunks::TrunksBinderService service;
87 #else
88   trunks::TrunksDBusService service;
89 #endif
90 
91   // Chain together command transceivers:
92   //   [IPC] --> BackgroundCommandTransceiver
93   //         --> ResourceManager
94   //         --> TpmHandle
95   //         --> [TPM]
96   trunks::CommandTransceiver *low_level_transceiver;
97   if (cl->HasSwitch("ftdi")) {
98     LOG(INFO) << "Sending commands to FTDI SPI.";
99     low_level_transceiver = new trunks::TrunksFtdiSpi();
100   } else if (cl->HasSwitch("simulator")) {
101     LOG(INFO) << "Sending commands to simulator.";
102     low_level_transceiver = new trunks::TpmSimulatorHandle();
103   } else {
104     low_level_transceiver = new trunks::TpmHandle();
105   }
106   CHECK(low_level_transceiver->Init())
107       << "Error initializing TPM communication.";
108   // This needs to be *after* opening the TPM handle and *before* starting the
109   // background thread.
110   InitMinijailSandbox();
111   base::Thread background_thread(kBackgroundThreadName);
112   CHECK(background_thread.Start()) << "Failed to start background thread.";
113   trunks::TrunksFactoryImpl factory(low_level_transceiver);
114   trunks::ResourceManager resource_manager(factory, low_level_transceiver);
115   background_thread.task_runner()->PostNonNestableTask(
116       FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
117                             base::Unretained(&resource_manager)));
118   trunks::BackgroundCommandTransceiver background_transceiver(
119       &resource_manager, background_thread.task_runner());
120   service.set_transceiver(&background_transceiver);
121   LOG(INFO) << "Trunks service started.";
122   return service.Run();
123 }
124