mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-04 08:54:20 +01:00
Merge 'Disable extension loading at runtime' from Preston Thorpe
SQLite disables the `load_extension` function by default in the core library. There are a couple reasons we should do the same. 1. VTab extensions need up to update the schema, and if there are multiple connections we can/will corrupt the schema or read garbage memory if an extension is loaded while another connection changes the schema. 2. for _general security reasons_ ™️, which is why sqlite disables this by default. This PR leaves it enabled in the CLI, where there can be only a single connection due to the lack of multi-process support right now. Closes #3250
This commit is contained in:
@@ -28,7 +28,7 @@ ctrlc = "3.4.4"
|
||||
dirs = "5.0.1"
|
||||
env_logger = { workspace = true }
|
||||
libc = "0.2.172"
|
||||
turso_core = { path = "../core", default-features = true, features = [] }
|
||||
turso_core = { path = "../core", default-features = true, features = ["cli_only"] }
|
||||
limbo_completion = { path = "../extensions/completion", features = ["static"] }
|
||||
miette = { workspace = true, features = ["fancy"] }
|
||||
nu-ansi-term = {version = "0.50.1", features = ["serde", "derive_serde_style"]}
|
||||
|
||||
@@ -184,7 +184,8 @@ impl Limbo {
|
||||
.with_mvcc(opts.experimental_mvcc)
|
||||
.with_indexes(indexes_enabled)
|
||||
.with_views(opts.experimental_views)
|
||||
.with_strict(opts.experimental_strict),
|
||||
.with_strict(opts.experimental_strict)
|
||||
.turso_cli(),
|
||||
None,
|
||||
)?;
|
||||
let conn = db.connect()?;
|
||||
|
||||
@@ -30,6 +30,7 @@ serde = ["dep:serde"]
|
||||
series = []
|
||||
encryption = []
|
||||
checksum = []
|
||||
cli_only = []
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
io-uring = { version = "0.7.5", optional = true }
|
||||
|
||||
@@ -316,6 +316,7 @@ mod tests {
|
||||
enable_indexes: false,
|
||||
enable_views: true,
|
||||
enable_strict: false,
|
||||
enable_load_extension: false,
|
||||
},
|
||||
None,
|
||||
)?;
|
||||
|
||||
12
core/lib.rs
12
core/lib.rs
@@ -106,6 +106,7 @@ pub struct DatabaseOpts {
|
||||
pub enable_indexes: bool,
|
||||
pub enable_views: bool,
|
||||
pub enable_strict: bool,
|
||||
enable_load_extension: bool,
|
||||
}
|
||||
|
||||
impl Default for DatabaseOpts {
|
||||
@@ -115,6 +116,7 @@ impl Default for DatabaseOpts {
|
||||
enable_indexes: true,
|
||||
enable_views: false,
|
||||
enable_strict: false,
|
||||
enable_load_extension: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,6 +126,12 @@ impl DatabaseOpts {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[cfg(feature = "cli_only")]
|
||||
pub fn turso_cli(mut self) -> Self {
|
||||
self.enable_load_extension = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_mvcc(mut self, enable: bool) -> Self {
|
||||
self.enable_mvcc = enable;
|
||||
self
|
||||
@@ -755,6 +763,10 @@ impl Database {
|
||||
Ok((io, db))
|
||||
}
|
||||
|
||||
pub(crate) fn can_load_extensions(&self) -> bool {
|
||||
self.opts.enable_load_extension
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn with_schema_mut<T>(&self, f: impl FnOnce(&mut Schema) -> Result<T>) -> Result<T> {
|
||||
let mut schema_ref = self.schema.lock().map_err(|_| LimboError::SchemaLocked)?;
|
||||
|
||||
@@ -4781,6 +4781,9 @@ pub fn op_function(
|
||||
#[cfg(feature = "fs")]
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
ScalarFunc::LoadExtension => {
|
||||
if !program.connection.db.can_load_extensions() {
|
||||
crate::bail_parse_error!("runtime extension loading is disabled");
|
||||
}
|
||||
let extension = &state.registers[*start_reg];
|
||||
let ext = resolve_ext_path(&extension.get_value().to_string())?;
|
||||
program.connection.load_extension(ext)?;
|
||||
|
||||
Reference in New Issue
Block a user