sqlite-loadable-rs
sqlite-loadable-rs copied to clipboard
Maybe unsound in set_argv_index and set_omit
hello, thank you for your contribution in this project, I am scanning the unsoundness problem in rust project. I notice the following code:
pub fn set_argv_index(&mut self, i: i32) {
unsafe { (*self.usage).argvIndex = i };
}
pub fn set_omit(&mut self, value: bool) {
unsafe { (*self.usage).omit = u8::from(value) }
}
Considering that pub mod table and usage is a pub field, I assume that users can directly manipulate this field, and that set_argv_index is a public function. This potential situation could result in self.usage being a null pointer, and directly dereferencing it might trigger undefined behavior (UB). For safety reasons, I felt it necessary to report this issue. If you have performed checks elsewhere that ensure this is safe, please don’t take offense at my raising this issue.
other unsoundness function are samilar, the scan result is below: ===== Pattern1 (Parameter Directly Used in Unsafe Operation) Report ===== 13:53:40|RAP|INFO|: 1: Public function with direct parameter to unsafe operation: table::define_table_function 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_59, _60, _64, _66, _67), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 2: Public function with direct parameter to unsafe operation: api::value_text 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_text(_11), 13:53:40|RAP|INFO|: (2) std::slice::from_raw_parts(_15, _16), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 3: Public function with direct parameter to unsafe operation: api::result_int64 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_int64(_4, _5), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 4: Public function with direct parameter to unsafe operation: table::IndexInfo::set_idxnum 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_4, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 5: Public function with direct parameter to unsafe operation: api::value_is_null 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_type(_3), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 6: Public function with direct parameter to unsafe operation: api::result_text 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_text(_24, _25, _28, _29), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 7: Public function with direct parameter to unsafe operation: api::value_int64 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_int64(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 8: Public function with direct parameter to unsafe operation: entrypoints::register_entrypoint 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::faux_sqlite_extension_init2(_7), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 9: Public function with direct parameter to unsafe operation: api::value_subtype 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_subtype(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 10: Public function with direct parameter to unsafe operation: table::define_table_function_with_find 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_60, _61, _65, _67, _68), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 11: Public function with direct parameter to unsafe operation: table::IndexInfo::set_idxstr 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_18, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 12: Public function with direct parameter to unsafe operation: table::define_virtual_table_with_find 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_61, _62, _66, _68, _69), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 13: Public function with direct parameter to unsafe operation: api::result_subtype 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_subtype(_4, _5), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 14: Public function with direct parameter to unsafe operation: table::define_virtual_table_writeable_with_transactions 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_65, _66, _70, _72, _73), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 15: Public function with direct parameter to unsafe operation: table::Constraint::set_omit 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_5, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 16: Public function with direct parameter to unsafe operation: api::value_type 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_type(_3), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 17: Public function with direct parameter to unsafe operation: api::result_null 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_null(_3), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 18: Public function with direct parameter to unsafe operation: api::result_pointer 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_pointer(_10, _11, _12, _16), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 19: Public function with direct parameter to unsafe operation: api::value_bytes 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_bytes(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 20: Public function with direct parameter to unsafe operation: api::result_int 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_int(_4, _5), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 21: Public function with direct parameter to unsafe operation: api::overload_function 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_overload_function(_14, _15, _19), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 22: Public function with direct parameter to unsafe operation: entrypoints::register_entrypoint_load_permanently 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::faux_sqlite_extension_init2(_7), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 23: Public function with direct parameter to unsafe operation: table::IndexInfo::set_estimated_rows 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_4, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 24: Public function with direct parameter to unsafe operation: collation::define_collation 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_collation_v2(_17, _18, _22, _23, _25, _27), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 25: Public function with direct parameter to unsafe operation: api::auxdata_get 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_get_auxdata(_3, _4), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 26: Public function with direct parameter to unsafe operation: api::result_blob 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_blob(_7, _8, _11), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 27: Public function with direct parameter to unsafe operation: table::define_virtual_table 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_59, _60, _64, _66, _67), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 28: Public function with direct parameter to unsafe operation: table::Constraint::set_argv_index 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_5, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 29: Public function with direct parameter to unsafe operation: api::auxdata_set 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_set_auxdata(_6, _7, _8, _9), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 30: Public function with direct parameter to unsafe operation: table::define_virtual_table_writeable 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_61, _62, _66, _68, _69), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 31: Public function with direct parameter to unsafe operation: table::define_virtual_table_writeablex 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_create_module_v2(_60, _61, _65, _67, _68), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 32: Public function with direct parameter to unsafe operation: table::IndexInfo::set_estimated_cost 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) *_4, 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 33: Public function with direct parameter to unsafe operation: api::result_double 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_double(_4, _5), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 34: Public function with direct parameter to unsafe operation: api::value_blob 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_blob(_6), 13:53:40|RAP|INFO|: (2) std::slice::from_raw_parts(_9, _11), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 35: Public function with direct parameter to unsafe operation: api::context_db_handle 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_context_db_handle(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 36: Public function with direct parameter to unsafe operation: api::result_error 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_error(_20, _21, _23), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 37: Public function with direct parameter to unsafe operation: api::result_error_code 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_result_error_code(_4, _5), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 38: Public function with direct parameter to unsafe operation: api::mprintf 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_mprintf(_14), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 39: Public function with direct parameter to unsafe operation: api::value_double 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_double(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 40: Public function with direct parameter to unsafe operation: api::value_text_notnull 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_text(_12), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: 41: Public function with direct parameter to unsafe operation: api::value_int 13:53:40|RAP|INFO|: unsafe operations: 13:53:40|RAP|INFO|: (1) ext::sqlite3ext_value_int(_2), 13:53:40|RAP|INFO|:
13:53:40|RAP|INFO|: Total pattern1 functions found: 41 13:53:40|RAP|INFO|:
here is my PoC:
use std::ptr;
pub struct sqlite3_index_info_sqlite3_index_constraint_usage {
pub argvIndex: i32,
pub omit: u8,
}
pub struct Constraint {
//pub constraint: sqlite3_index_info_sqlite3_index_constraint,
pub usage: *mut sqlite3_index_info_sqlite3_index_constraint_usage,
// needed for sqlite3_vtab_* methods
//index_info: *mut sqlite3_index_info,
constraint_idx: i32,
}
impl Constraint {
pub fn set_argv_index(&mut self, i: i32) {
unsafe { (*self.usage).argvIndex = i };
}
pub fn set_omit(&mut self, value: bool) {
unsafe { (*self.usage).omit = u8::from(value) }
}
}
fn main(){
let a:*mut sqlite3_index_info_sqlite3_index_constraint_usage= ptr::null_mut();
let mut b=Constraint{usage: a, constraint_idx: 0};
b.set_argv_index(1);
}
I annotated and modified parts of the implementation for convenience, but I believe the overall framework is consistent.
Maybe same unsoundness problem for https://github.com/asg017/sqlite-loadable-rs/blob/2c5c049c0c9e010a70b458fde459facf294befce/src/table.rs#L253 but this is because the new method didn't varify the pointer validity. and if pass a null pointer it may cause UB in https://github.com/asg017/sqlite-loadable-rs/blob/2c5c049c0c9e010a70b458fde459facf294befce/src/table.rs#L268