diff options
author | Utkarsh Sanghi <usanghi@chromium.org> | 2015-08-14 09:34:31 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-20 00:12:17 +0000 |
commit | e6419641bfebd76cbe5fffe3877c068af6b1c396 (patch) | |
tree | e88462c58bade1f7fb5af7325f2d1a673b255421 | |
parent | d4f8415e562a42a181103a30e107fc1aeee9eb9b (diff) | |
download | tpm_manager-e6419641bfebd76cbe5fffe3877c068af6b1c396.tar.gz |
tpm_manager: Add LocalDataStore implementation
BUG=None
TEST=check if file is created and read on DUT
Change-Id: I8ab50a7354eb26d6ea89cc68f7ed097972bc63ee
Reviewed-on: https://chromium-review.googlesource.com/293589
Tested-by: Utkarsh Sanghi <usanghi@chromium.org>
Reviewed-by: Darren Krahn <dkrahn@chromium.org>
Commit-Queue: Utkarsh Sanghi <usanghi@chromium.org>
-rw-r--r-- | server/local_data_store_impl.cc | 86 | ||||
-rw-r--r-- | server/local_data_store_impl.h | 33 | ||||
-rw-r--r-- | server/main.cc | 35 | ||||
-rw-r--r-- | server/tpm_manager_service.cc | 6 | ||||
-rw-r--r-- | server/tpm_manager_service.h | 12 | ||||
-rw-r--r-- | server/tpm_manager_service_test.cc | 7 | ||||
-rw-r--r-- | server/tpm_managerd.conf | 6 | ||||
-rw-r--r-- | tpm_manager.gyp | 3 |
8 files changed, 145 insertions, 43 deletions
diff --git a/server/local_data_store_impl.cc b/server/local_data_store_impl.cc new file mode 100644 index 0000000..ca7c9bc --- /dev/null +++ b/server/local_data_store_impl.cc @@ -0,0 +1,86 @@ +// Copyright 2015 The Chromium OS 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 "tpm_manager/server/local_data_store_impl.h" + +#include <fcntl.h> + +#include <string> + +#include <base/files/file_path.h> +#include <base/files/file_util.h> +#include <base/files/important_file_writer.h> + +using base::FilePath; + +namespace tpm_manager { + +const char kTpmLocalDataFile[] = + "/mnt/stateful/unencrypted/preserve/local_tpm_data"; +const mode_t kLocalDataPermissions = 0600; + +bool LocalDataStoreImpl::Read(LocalData* data) { + CHECK(data); + const int kMask = base::FILE_PERMISSION_OTHERS_MASK; + FilePath path(kTpmLocalDataFile); + int permissions = 0; + if (base::GetPosixFilePermissions(path, &permissions) && + (permissions & kMask) != 0) { + base::SetPosixFilePermissions(path, permissions & ~kMask); + } + std::string file_data; + if (!ReadFileToString(path, &file_data)) { + LOG(ERROR) << "Error reading data store file."; + return false; + } + if (!data->ParseFromString(file_data)) { + LOG(ERROR) << "Error parsing file data into protobuf."; + return false; + } + return true; +} + +bool LocalDataStoreImpl::Write(const LocalData& data) { + std::string file_data; + if (!data.SerializeToString(&file_data)) { + LOG(ERROR) << "Error serializing file to string."; + return false; + } + FilePath path(kTpmLocalDataFile); + if (!base::CreateDirectory(path.DirName())) { + LOG(ERROR) << "Cannot create directory: " << path.DirName().value(); + return false; + } + if (!base::ImportantFileWriter::WriteFileAtomically(path, file_data)) { + LOG(ERROR) << "Failed to write file: " << path.value(); + return false; + } + if (!base::SetPosixFilePermissions(path, kLocalDataPermissions)) { + LOG(ERROR) << "Failed to set permissions for file: " << path.value(); + return false; + } + // Sync the parent directory. + std::string dir_name = path.DirName().value(); + int dir_fd = HANDLE_EINTR(open(dir_name.c_str(), O_RDONLY|O_DIRECTORY)); + if (dir_fd < 0) { + PLOG(WARNING) << "Could not open " << dir_name << " for syncing"; + return false; + } + // POSIX specifies EINTR as a possible return value of fsync(). + int result = HANDLE_EINTR(fsync(dir_fd)); + if (result < 0) { + PLOG(WARNING) << "Failed to sync " << dir_name; + close(dir_fd); + return false; + } + // close() may not be retried on error. + result = IGNORE_EINTR(close(dir_fd)); + if (result < 0) { + PLOG(WARNING) << "Failed to close after sync " << dir_name; + return false; + } + return true; +} + +} // namespace tpm_manager diff --git a/server/local_data_store_impl.h b/server/local_data_store_impl.h new file mode 100644 index 0000000..cb2d897 --- /dev/null +++ b/server/local_data_store_impl.h @@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TPM_MANAGER_SERVER_LOCAL_DATA_STORE_IMPL_H_ +#define TPM_MANAGER_SERVER_LOCAL_DATA_STORE_IMPL_H_ + +#include "tpm_manager/server/local_data_store.h" + +#include <string> + +#include <base/macros.h> + +namespace tpm_manager { + +class LocalDataStoreImpl : public LocalDataStore { + public: + LocalDataStoreImpl() = default; + ~LocalDataStoreImpl() override = default; + + // LocalDataStore methods. + bool Read(LocalData* data) override; + bool Write(const LocalData& data) override; + + private: + DISALLOW_COPY_AND_ASSIGN(LocalDataStoreImpl); +}; + + +} // namespace tpm_manager + + +#endif // TPM_MANAGER_SERVER_LOCAL_DATA_STORE_IMPL_H_ diff --git a/server/main.cc b/server/main.cc index 17f906b..f153c55 100644 --- a/server/main.cc +++ b/server/main.cc @@ -14,47 +14,24 @@ #include "tpm_manager/common/dbus_interface.h" #include "tpm_manager/server/dbus_service.h" +#include "tpm_manager/server/local_data_store_impl.h" #include "tpm_manager/server/tpm_manager_service.h" using chromeos::dbus_utils::AsyncEventSequencer; namespace { -const uid_t kRootUID = 0; -const char kTpmManagerUser[] = "tpm_manager"; -const char kTpmManagerGroup[] = "tpm_manager"; -const char kTpmManagerSeccompPath[] = - "/usr/share/policy/tpm_managerd-seccomp.policy"; const char kWaitForOwnershipTriggerSwitch[] = "wait_for_ownership_trigger"; - -void InitMinijailSandbox() { - uid_t tpm_manager_uid; - gid_t tpm_manager_gid; - CHECK(chromeos::userdb::GetUserInfo(kTpmManagerUser, - &tpm_manager_uid, - &tpm_manager_gid)) - << "Error getting tpm_manager uid and gid."; - CHECK_EQ(getuid(), kRootUID) << "TpmManagerDaemon not initialized as root."; - chromeos::Minijail* minijail = chromeos::Minijail::GetInstance(); - struct minijail* jail = minijail->New(); - minijail->DropRoot(jail, kTpmManagerUser, kTpmManagerGroup); - minijail->UseSeccompFilter(jail, kTpmManagerSeccompPath); - minijail->Enter(jail); - minijail->Destroy(jail); - CHECK_EQ(getuid(), tpm_manager_uid) - << "TpmManagerDaemon was not able to drop to tpm_manager user."; - CHECK_EQ(getgid(), tpm_manager_gid) - << "TpmManagerDaemon was not able to drop to tpm_manager group."; -} - class TpmManagerDaemon : public chromeos::DBusServiceDaemon { public: TpmManagerDaemon() : chromeos::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + local_data_store_.reset(new tpm_manager::LocalDataStoreImpl()); tpm_manager_service_.reset(new tpm_manager::TpmManagerService( - command_line->HasSwitch(kWaitForOwnershipTriggerSwitch))); + command_line->HasSwitch(kWaitForOwnershipTriggerSwitch), + local_data_store_.get())); } protected: @@ -75,6 +52,7 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon { } private: + std::unique_ptr<tpm_manager::LocalDataStore> local_data_store_; std::unique_ptr<tpm_manager::TpmManagerInterface> tpm_manager_service_; std::unique_ptr<tpm_manager::DBusService> dbus_service_; @@ -86,8 +64,7 @@ class TpmManagerDaemon : public chromeos::DBusServiceDaemon { int main(int argc, char* argv[]) { base::CommandLine::Init(argc, argv); chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr); - InitMinijailSandbox(); TpmManagerDaemon daemon; - LOG(INFO) << "TpmManager Daemon Started"; + LOG(INFO) << "TpmManager Daemon Started."; return daemon.Run(); } diff --git a/server/tpm_manager_service.cc b/server/tpm_manager_service.cc index dc7e284..0ec166e 100644 --- a/server/tpm_manager_service.cc +++ b/server/tpm_manager_service.cc @@ -10,8 +10,10 @@ namespace tpm_manager { -TpmManagerService::TpmManagerService(bool wait_for_ownership) - : wait_for_ownership_(wait_for_ownership), +TpmManagerService::TpmManagerService(bool wait_for_ownership, + LocalDataStore* local_data_store) + : local_data_store_(local_data_store), + wait_for_ownership_(wait_for_ownership), weak_factory_(this) { } diff --git a/server/tpm_manager_service.h b/server/tpm_manager_service.h index 56144ee..95c42d3 100644 --- a/server/tpm_manager_service.h +++ b/server/tpm_manager_service.h @@ -42,8 +42,10 @@ namespace tpm_manager { class TpmManagerService : public TpmManagerInterface { public: // If |wait_for_ownership| is set, TPM initialization will be postponed until - // an explicit TakeOwnership request is received. - explicit TpmManagerService(bool wait_for_ownership); + // an explicit TakeOwnership request is received. Does not take ownership of + // |local_data_store|. + explicit TpmManagerService(bool wait_for_ownership, + LocalDataStore* local_data_store); ~TpmManagerService() override = default; // TpmManagerInterface methods. @@ -54,10 +56,6 @@ class TpmManagerService : public TpmManagerInterface { const TakeOwnershipCallback& callback) override; // Mutators useful for injecting dependencies for testing. - void set_local_data_store(LocalDataStore* local_data_store) { - local_data_store_ = local_data_store; - } - void set_tpm_initializer(TpmInitializer* initializer) { tpm_initializer_ = initializer; } @@ -92,7 +90,7 @@ class TpmManagerService : public TpmManagerInterface { // effect. void InitializeTask(); - LocalDataStore* local_data_store_{nullptr}; + LocalDataStore* local_data_store_; TpmInitializer* tpm_initializer_{nullptr}; TpmStatus* tpm_status_{nullptr}; // Whether to wait for an explicit call to 'TakeOwnership' before initializing diff --git a/server/tpm_manager_service_test.cc b/server/tpm_manager_service_test.cc index 337cd72..521b4de 100644 --- a/server/tpm_manager_service_test.cc +++ b/server/tpm_manager_service_test.cc @@ -26,7 +26,8 @@ class TpmManagerServiceTest : public testing::Test { public: ~TpmManagerServiceTest() override = default; void SetUp() override { - service_.reset(new TpmManagerService(true /*wait_for_ownership*/)); + service_.reset(new TpmManagerService(true /*wait_for_ownership*/, + &mock_local_data_store_)); SetupService(); } @@ -51,7 +52,6 @@ class TpmManagerServiceTest : public testing::Test { } void SetupService() { - service_->set_local_data_store(&mock_local_data_store_); service_->set_tpm_initializer(&mock_tpm_initializer_); service_->set_tpm_status(&mock_tpm_status_); CHECK(service_->Initialize()); @@ -72,7 +72,8 @@ class TpmManagerServiceTest_NoWaitForOwnership : public TpmManagerServiceTest { public: ~TpmManagerServiceTest_NoWaitForOwnership() override = default; void SetUp() override { - service_.reset(new TpmManagerService(false /*wait_for_ownership*/)); + service_.reset(new TpmManagerService(false /*wait_for_ownership*/, + &mock_local_data_store_)); } }; diff --git a/server/tpm_managerd.conf b/server/tpm_managerd.conf index daed87f..60b5bc8 100644 --- a/server/tpm_managerd.conf +++ b/server/tpm_managerd.conf @@ -9,4 +9,8 @@ start on starting system-services stop on stopping system-services respawn -exec /usr/sbin/tpm_managerd +# Minijail forks off our process +expect fork + +exec minijail0 -i -g tpm_manager -u tpm_manager -G -n \ + -S /usr/share/policy/tpm_managerd-seccomp.policy /usr/sbin/tpm_managerd diff --git a/tpm_manager.gyp b/tpm_manager.gyp index ffa96e7..a438484 100644 --- a/tpm_manager.gyp +++ b/tpm_manager.gyp @@ -56,8 +56,9 @@ 'target_name': 'server_library', 'type': 'static_library', 'sources': [ - 'server/tpm_manager_service.cc', 'server/dbus_service.cc', + 'server/local_data_store_impl.cc', + 'server/tpm_manager_service.cc', ], 'dependencies': [ 'proto_library', |