sandboxed_vfs.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef SQL_SANDBOXED_VFS_H_
  5. #define SQL_SANDBOXED_VFS_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include "base/component_export.h"
  9. #include "base/files/file.h"
  10. #include "base/files/file_path.h"
  11. #include "base/time/time.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "third_party/sqlite/sqlite3.h"
  14. namespace sql {
  15. // SQLite VFS file implementation that works in a sandboxed process.
  16. //
  17. // Instances are thread-friendly.
  18. class COMPONENT_EXPORT(SQL) SandboxedVfs {
  19. public:
  20. // Describes access rights for a path, used by Delegate::GetPathAccess below.
  21. struct PathAccessInfo {
  22. bool can_read = false;
  23. bool can_write = false;
  24. };
  25. // Environment-specific SandboxedVfs implementation details.
  26. //
  27. // This abstracts a handful of operations that don't typically work in a
  28. // sandbox environment given a typical naive implementation. Instances must be
  29. // thread-safe.
  30. class Delegate {
  31. public:
  32. virtual ~Delegate() = default;
  33. // Opens a file.
  34. //
  35. // `file_path` is the parsed version of a path passed by SQLite to Open().
  36. // `sqlite_requested_flags` is a bitwise combination SQLite flags used when
  37. // opening files. Returns the opened File on success, or an invalid File on
  38. // failure.
  39. virtual base::File OpenFile(const base::FilePath& file_path,
  40. int sqlite_requested_flags) = 0;
  41. // Deletes a file.
  42. //
  43. // `file_path` is the parsed version of a path passed by SQLite to Delete().
  44. // If `sync_dir` is true, the implementation should attempt to flush to disk
  45. // the changes to the file's directory, to ensure that the deletion is
  46. // reflected after a power failure. Returns an SQLite error code indicating
  47. // the status of the operation.
  48. virtual int DeleteFile(const base::FilePath& file_path, bool sync_dir) = 0;
  49. // Queries path access information for `file_path`. Returns null if the
  50. // given path does not exist.
  51. virtual absl::optional<PathAccessInfo> GetPathAccess(
  52. const base::FilePath& file_path) = 0;
  53. // Resizes a file.
  54. //
  55. // `file` is the result of a previous call to Delegate::OpenFile() with
  56. // `file_path`. `size` is the new desired size in bytes, and may be smaller
  57. // or larger than the current file size. Returns true if successful and
  58. // false otherwise.
  59. //
  60. // Implementations can modify `file` directly, or operate on the filesystem
  61. // via `file_path`.
  62. //
  63. // This is only called after the direct approach of base::File::SetLength()
  64. // fails. So, the implementation should not bother trying to call
  65. // SetLength() on `file`. This currently only happens on macOS < 10.15.
  66. virtual bool SetFileLength(const base::FilePath& file_path,
  67. base::File& file,
  68. size_t size) = 0;
  69. };
  70. // We don't allow SandboxedVfs instances to be destroyed. Once created, they
  71. // are permanently registered in the calling process.
  72. ~SandboxedVfs() = delete;
  73. // Constructs a new instance of ths object using `delegate` to support various
  74. // operations from within the sandbox. The VFS is registered with SQLite under
  75. // `name` and if `make_default` is true then the VFS is also set as the global
  76. // default for new database instances within the calling process.
  77. //
  78. // Note that `name` must be globally unique to the calling process.
  79. static void Register(const char* name,
  80. std::unique_ptr<Delegate> delegate,
  81. bool make_default);
  82. Delegate* delegate() const { return delegate_.get(); }
  83. // sqlite3_vfs implementation.
  84. int Open(const char* full_path,
  85. sqlite3_file& result_file,
  86. int requested_flags,
  87. int* granted_flags);
  88. int Delete(const char* full_path, int sync_dir);
  89. int Access(const char* full_path, int flags, int& result);
  90. int FullPathname(const char* file_path, int result_size, char* result);
  91. int Randomness(int result_size, char* result);
  92. int Sleep(int microseconds);
  93. int GetLastError(int message_size, char* message) const;
  94. int CurrentTimeInt64(sqlite3_int64* result_ms);
  95. // Used by SandboxedVfsFile.
  96. void SetLastError(base::File::Error error) { this->last_error_ = error; }
  97. private:
  98. SandboxedVfs(const char* name,
  99. std::unique_ptr<Delegate> delegate,
  100. bool make_default);
  101. sqlite3_vfs sandboxed_vfs_;
  102. const base::Time sqlite_epoch_;
  103. const std::unique_ptr<Delegate> delegate_;
  104. base::File::Error last_error_;
  105. };
  106. } // namespace sql
  107. #endif // SQL_SANDBOXED_VFS_H_