| // Copyright 2018 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef INIT_MOUNT_ENCRYPTED_ENCRYPTED_FS_H_ | |
| #define INIT_MOUNT_ENCRYPTED_ENCRYPTED_FS_H_ | |
| #include <inttypes.h> | |
| #include <sys/stat.h> | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include <base/files/file_path.h> | |
| #include <brillo/brillo_export.h> | |
| #include <brillo/secure_blob.h> | |
| #include <libstorage/platform/platform.h> | |
| #include <libstorage/storage_container/filesystem_key.h> | |
| #include <libstorage/storage_container/storage_container.h> | |
| #include <libstorage/storage_container/storage_container_factory.h> | |
| namespace mount_encrypted { | |
| // Teardown stage: for granular teardowns | |
| enum class TeardownStage { | |
| kTeardownUnbind, | |
| kTeardownContainer, | |
| }; | |
| // BindMount represents a bind mount to be setup from | |
| // source directories within the encrypted mount. | |
| // EncryptedFs is responsible for setting up the bind mount | |
| // once it sets up the encrypted mount. | |
| struct BindMount { | |
| base::FilePath src; // Location of bind source. | |
| base::FilePath dst; // Destination of bind. | |
| uid_t owner; | |
| gid_t group; | |
| mode_t mode; | |
| bool submount; // Submount is bound already. | |
| }; | |
| // EncryptedFs sets up, tears down and cleans up encrypted | |
| // stateful mounts. Given a root directory, the class | |
| // sets up an encrypted mount at <root_dir>/ENCRYPTED_MOUNT. | |
| class BRILLO_EXPORT EncryptedFs { | |
| public: | |
| // Set up the encrypted filesystem.. | |
| EncryptedFs(const base::FilePath& rootdir, | |
| const base::FilePath& statefulmnt, | |
| uint64_t fs_size, | |
| const std::string& dmcrypt_name, | |
| std::unique_ptr<libstorage::StorageContainer> container, | |
| libstorage::Platform* platform); | |
| ~EncryptedFs() = default; | |
| static std::unique_ptr<EncryptedFs> Generate( | |
| const base::FilePath& rootdir, | |
| const base::FilePath& statefulmnt, | |
| libstorage::Platform* platform, | |
| libstorage::StorageContainerFactory* storage_container_factory); | |
| // Setup mounts the encrypted mount by: | |
| // 1. Create a sparse file at <rootdir>/STATEFUL_MNT/encrypted.block | |
| // 2. Mounting a loop device on top of the sparse file. | |
| // 3. Mounting a dmcrypt device with the loop device as the backing | |
| // device and the provided encryption key. | |
| // 4. Formatting the dmcrypt device as ext4 and mounting it at the | |
| // mount_point. | |
| // If a sparse file already exists, Setup assumes that the stateful | |
| // mount has already been setup and attempts to mount the | |
| // | ext4 | dmcrypt | loopback | tower on top of the sparse file. | |
| // Parameters | |
| // encryption_key - dmcrypt encryption key. | |
| // rebuild - cleanup and recreate the encrypted mount. | |
| bool Setup(const libstorage::FileSystemKey& encryption_key, bool rebuild); | |
| // Purge - obliterate the sparse file. This should be called only | |
| // when the encrypted fs is not mounted. | |
| bool Purge(); | |
| // Teardown - stepwise unmounts the | ext4 | dmcrypt | loopback | tower | |
| // on top of the sparse file. | |
| bool Teardown(); | |
| // CheckStates - Checks validity for the stateful mount before mounting. | |
| bool CheckStates(); | |
| // ReportInfo - Reports the paths and bind mounts. | |
| bool ReportInfo() const; | |
| private: | |
| friend class EncryptedFsTest; | |
| FRIEND_TEST(EncryptedFsTest, RebuildStateful); | |
| FRIEND_TEST(EncryptedFsTest, OldStateful); | |
| FRIEND_TEST(EncryptedFsTest, LoopdevTeardown); | |
| FRIEND_TEST(EncryptedFsTest, DevmapperTeardown); | |
| // TeardownByStage allows higher granularity over teardown | |
| // processes. | |
| bool TeardownByStage(TeardownStage stage, bool ignore_errors); | |
| // Root directory to use for the encrypted stateful filesystem. | |
| const base::FilePath rootdir_; | |
| // Size of the filesystem. | |
| const uint64_t fs_size_; | |
| // Dm-crypt device name: used for key finalization. | |
| const std::string dmcrypt_name_; | |
| // File paths used by encrypted stateful. | |
| const base::FilePath stateful_mount_; | |
| const base::FilePath dmcrypt_dev_; | |
| const base::FilePath encrypted_mount_; | |
| // Use a raw Platform pointer to avoid convoluted EXPECT_CALL semantics | |
| // for mock Platform objects. | |
| libstorage::Platform* platform_; | |
| // Encrypted container that will be mounted as the encrypted filesystem. | |
| std::unique_ptr<libstorage::StorageContainer> container_; | |
| std::vector<BindMount> bind_mounts_; | |
| }; | |
| } // namespace mount_encrypted | |
| #endif // INIT_MOUNT_ENCRYPTED_ENCRYPTED_FS_H_ |