123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // Copyright 2019 The Chromium 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 SQL_SANDBOXED_VFS_H_
- #define SQL_SANDBOXED_VFS_H_
- #include <stdint.h>
- #include <memory>
- #include "base/component_export.h"
- #include "base/files/file.h"
- #include "base/files/file_path.h"
- #include "base/time/time.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "third_party/sqlite/sqlite3.h"
- namespace sql {
- // SQLite VFS file implementation that works in a sandboxed process.
- //
- // Instances are thread-friendly.
- class COMPONENT_EXPORT(SQL) SandboxedVfs {
- public:
- // Describes access rights for a path, used by Delegate::GetPathAccess below.
- struct PathAccessInfo {
- bool can_read = false;
- bool can_write = false;
- };
- // Environment-specific SandboxedVfs implementation details.
- //
- // This abstracts a handful of operations that don't typically work in a
- // sandbox environment given a typical naive implementation. Instances must be
- // thread-safe.
- class Delegate {
- public:
- virtual ~Delegate() = default;
- // Opens a file.
- //
- // `file_path` is the parsed version of a path passed by SQLite to Open().
- // `sqlite_requested_flags` is a bitwise combination SQLite flags used when
- // opening files. Returns the opened File on success, or an invalid File on
- // failure.
- virtual base::File OpenFile(const base::FilePath& file_path,
- int sqlite_requested_flags) = 0;
- // Deletes a file.
- //
- // `file_path` is the parsed version of a path passed by SQLite to Delete().
- // If `sync_dir` is true, the implementation should attempt to flush to disk
- // the changes to the file's directory, to ensure that the deletion is
- // reflected after a power failure. Returns an SQLite error code indicating
- // the status of the operation.
- virtual int DeleteFile(const base::FilePath& file_path, bool sync_dir) = 0;
- // Queries path access information for `file_path`. Returns null if the
- // given path does not exist.
- virtual absl::optional<PathAccessInfo> GetPathAccess(
- const base::FilePath& file_path) = 0;
- // Resizes a file.
- //
- // `file` is the result of a previous call to Delegate::OpenFile() with
- // `file_path`. `size` is the new desired size in bytes, and may be smaller
- // or larger than the current file size. Returns true if successful and
- // false otherwise.
- //
- // Implementations can modify `file` directly, or operate on the filesystem
- // via `file_path`.
- //
- // This is only called after the direct approach of base::File::SetLength()
- // fails. So, the implementation should not bother trying to call
- // SetLength() on `file`. This currently only happens on macOS < 10.15.
- virtual bool SetFileLength(const base::FilePath& file_path,
- base::File& file,
- size_t size) = 0;
- };
- // We don't allow SandboxedVfs instances to be destroyed. Once created, they
- // are permanently registered in the calling process.
- ~SandboxedVfs() = delete;
- // Constructs a new instance of ths object using `delegate` to support various
- // operations from within the sandbox. The VFS is registered with SQLite under
- // `name` and if `make_default` is true then the VFS is also set as the global
- // default for new database instances within the calling process.
- //
- // Note that `name` must be globally unique to the calling process.
- static void Register(const char* name,
- std::unique_ptr<Delegate> delegate,
- bool make_default);
- Delegate* delegate() const { return delegate_.get(); }
- // sqlite3_vfs implementation.
- int Open(const char* full_path,
- sqlite3_file& result_file,
- int requested_flags,
- int* granted_flags);
- int Delete(const char* full_path, int sync_dir);
- int Access(const char* full_path, int flags, int& result);
- int FullPathname(const char* file_path, int result_size, char* result);
- int Randomness(int result_size, char* result);
- int Sleep(int microseconds);
- int GetLastError(int message_size, char* message) const;
- int CurrentTimeInt64(sqlite3_int64* result_ms);
- // Used by SandboxedVfsFile.
- void SetLastError(base::File::Error error) { this->last_error_ = error; }
- private:
- SandboxedVfs(const char* name,
- std::unique_ptr<Delegate> delegate,
- bool make_default);
- sqlite3_vfs sandboxed_vfs_;
- const base::Time sqlite_epoch_;
- const std::unique_ptr<Delegate> delegate_;
- base::File::Error last_error_;
- };
- } // namespace sql
- #endif // SQL_SANDBOXED_VFS_H_
|