1 // 2 // Copyright (C) 2015 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 "tpm_manager/server/local_data_store_impl.h" 18 19 #include <fcntl.h> 20 21 #include <string> 22 23 #include <base/files/file_path.h> 24 #include <base/files/file_util.h> 25 #include <base/files/important_file_writer.h> 26 27 using base::FilePath; 28 29 namespace tpm_manager { 30 31 #if defined(__ANDROID__) 32 const char kTpmLocalDataFile[] = "/data/misc/tpm_managerd/local_tpm_data"; 33 #else 34 const char kTpmLocalDataFile[] = "/var/lib/tpm_manager/local_tpm_data"; 35 #endif 36 const mode_t kLocalDataPermissions = 0600; 37 38 bool LocalDataStoreImpl::Read(LocalData* data) { 39 CHECK(data); 40 FilePath path(kTpmLocalDataFile); 41 if (!base::PathExists(path)) { 42 data->Clear(); 43 return true; 44 } 45 int permissions = 0; 46 if (base::GetPosixFilePermissions(path, &permissions) && 47 (permissions & ~kLocalDataPermissions) != 0) { 48 base::SetPosixFilePermissions(path, kLocalDataPermissions); 49 } 50 std::string file_data; 51 if (!ReadFileToString(path, &file_data)) { 52 LOG(ERROR) << "Error reading data store file."; 53 return false; 54 } 55 if (!data->ParseFromString(file_data)) { 56 LOG(ERROR) << "Error parsing file data into protobuf."; 57 return false; 58 } 59 return true; 60 } 61 62 bool LocalDataStoreImpl::Write(const LocalData& data) { 63 std::string file_data; 64 if (!data.SerializeToString(&file_data)) { 65 LOG(ERROR) << "Error serializing file to string."; 66 return false; 67 } 68 FilePath path(kTpmLocalDataFile); 69 if (!base::CreateDirectory(path.DirName())) { 70 LOG(ERROR) << "Cannot create directory: " << path.DirName().value(); 71 return false; 72 } 73 if (!base::ImportantFileWriter::WriteFileAtomically(path, file_data)) { 74 LOG(ERROR) << "Failed to write file: " << path.value(); 75 return false; 76 } 77 if (!base::SetPosixFilePermissions(path, kLocalDataPermissions)) { 78 LOG(ERROR) << "Failed to set permissions for file: " << path.value(); 79 return false; 80 } 81 // Sync the parent directory. 82 std::string dir_name = path.DirName().value(); 83 int dir_fd = HANDLE_EINTR(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY)); 84 if (dir_fd < 0) { 85 PLOG(WARNING) << "Could not open " << dir_name << " for syncing"; 86 return false; 87 } 88 // POSIX specifies EINTR as a possible return value of fsync(). 89 int result = HANDLE_EINTR(fsync(dir_fd)); 90 if (result < 0) { 91 PLOG(WARNING) << "Failed to sync " << dir_name; 92 close(dir_fd); 93 return false; 94 } 95 // close() may not be retried on error. 96 result = IGNORE_EINTR(close(dir_fd)); 97 if (result < 0) { 98 PLOG(WARNING) << "Failed to close after sync " << dir_name; 99 return false; 100 } 101 return true; 102 } 103 104 } // namespace tpm_manager 105