| // Copyright 2021 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 CRYPTOHOME_FAKE_PLATFORM_FAKE_MOUNT_MAPPER_H_ |
| #define CRYPTOHOME_FAKE_PLATFORM_FAKE_MOUNT_MAPPER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <unordered_map> |
| |
| #include <base/files/file_path.h> |
| |
| #include "cryptohome/fake_platform/real_fake_mount_mapping_redirect_factory.h" |
| |
| namespace cryptohome { |
| |
| // A wrapper class for a single mount mapping. |
| class FakeMountMapping final { |
| public: |
| FakeMountMapping(const FakeMountMapping& mapping) = default; |
| ~FakeMountMapping() = default; |
| |
| // Given the path, translate it from the target to the source. |
| base::FilePath TranslateTargetToSource(const base::FilePath&) const; |
| |
| // Given the path, translate it from the source to the target. |
| base::FilePath TranslateSourceToTarget(const base::FilePath&) const; |
| |
| // Given the path, translate it from the target to the redirect. |
| base::FilePath TranslateTargetToRedirect(const base::FilePath&) const; |
| |
| // Given the path, translate it from the redirect to the target. |
| base::FilePath TranslateRedirectToTarget(const base::FilePath&) const; |
| |
| const base::FilePath& GetSource() const; |
| const base::FilePath& GetTarget() const; |
| const base::FilePath& GetRedirect() const; |
| |
| private: |
| FakeMountMapping(const base::FilePath& source, |
| const base::FilePath& target, |
| const base::FilePath& redirect); |
| |
| const base::FilePath source_; |
| const base::FilePath target_; |
| const base::FilePath redirect_; |
| |
| friend class FakeMountMapper; |
| }; |
| |
| // FakeMountMapper maintains the mapping of mounts and provides a method to |
| // resolve the actual physical location of a path. |
| // The main internal concept of the class is a "redirect". |
| // Redirect is a directory, which is a physical location of the files shown |
| // under the mount target directory. |
| // In the case of Bind, redirect is a physical location of the |
| // source within tmpfs. |
| // In the case of Mount, redirect is a newly created /tmp/<unique id> directory, |
| // to simulate a persistent storage within a block device or encrypted fs. |
| class FakeMountMapper final { |
| public: |
| FakeMountMapper( |
| const base::FilePath& tmpfs_rootfs, |
| std::unique_ptr<FakeMountMappingRedirectFactory> redirect_factory = |
| std::make_unique<RealFakeMountMappingRedirectFactory>()); |
| ~FakeMountMapper(); |
| |
| bool Mount(const base::FilePath& source, const base::FilePath& target); |
| bool Bind(const base::FilePath& source, const base::FilePath& target); |
| bool Unmount(const base::FilePath& target); |
| |
| // Returns true if the path is a target of a Bind or Mount. |
| bool IsMounted(const base::FilePath& path) const; |
| |
| // Returns true if the path is a target or within a target of Bind or Mount. |
| bool IsOnMount(const base::FilePath& target) const; |
| |
| void ListMountsBySourcePrefix( |
| const std::string& source_prefix, |
| std::multimap<const base::FilePath, const base::FilePath>* mounts) const; |
| |
| void ListMountsBySourcePrefix( |
| const base::FilePath& source_prefix, |
| std::multimap<const base::FilePath, const base::FilePath>* mounts) const; |
| |
| // Translates a path within the "represented" file system to the actual |
| // physical location in tmpfs. |
| base::FilePath ResolvePath(const base::FilePath& path) const; |
| |
| // Transforms a physical location in tmpfs to a logical location within |
| // a "represented" filesystem. Since the transformation may yield multiple |
| // results (a directory mounted to multiple places), `expected_parent` defines |
| // which result should be used - it needs to be a child of `expected_parent`. |
| // If matching `expected_parent` also yields multiple results, then the method |
| // returns any matching path out of all possible (the choice is not guaranteed |
| // to be deterministic and may wary among invocations and program runs). |
| base::FilePath ReverseResolvePath( |
| const base::FilePath& path, const base::FilePath& expected_parent) const; |
| |
| private: |
| const base::FilePath tmpfs_rootfs_; |
| const std::unique_ptr<FakeMountMappingRedirectFactory> redirect_factory_; |
| |
| std::map<base::FilePath, FakeMountMapping> target_to_mount_; |
| std::unordered_map<base::FilePath, base::FilePath> source_to_redirect_; |
| |
| bool MountImpl(const base::FilePath& source, |
| const base::FilePath& target, |
| const base::FilePath& redirect); |
| |
| // Returns mapping if the target is or on the mount, base::nullopt otherwise. |
| std::optional<FakeMountMapping> FindMapping( |
| const base::FilePath& target) const; |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_FAKE_PLATFORM_FAKE_MOUNT_MAPPER_H_ |