[go: nahoru, domu]

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