CVE-2021-45713
Description
An issue was discovered in the rusqlite crate 0.25.x before 0.25.4 and 0.26.x before 0.26.2 for Rust. create_scalar_function has a use-after-free.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Use-after-free in rusqlite create_scalar_function prior to 0.25.4 and 0.26.2 due to incorrect closure lifetime bounds.
Vulnerability
The rusqlite crate for Rust versions 0.25.x before 0.25.4 and 0.26.x before 0.26.2 contains a use-after-free vulnerability in the create_scalar_function function. The bug arises because the closure passed to create_scalar_function is bound by an incorrect lifetime parameter, allowing the closure to be called after the associated Connection has been dropped [2].
Exploitation
An attacker can exploit this vulnerability by providing a scalar function implementation that captures a reference with a lifetime tied to the Connection. When the Connection is dropped, the closure's captured data becomes freed, but SQLite may still invoke the closure, leading to a use-after-free condition. No special privileges are required; any code that creates a scalar function with a non-'static closure and subsequently drops the Connection may trigger the issue.
Impact
Successfully exploiting the use-after-free can result in memory corruption, potentially leading to arbitrary code execution or information disclosure. The impact is limited by the memory safety guarantees of Rust, but unsafe code paths in the underlying SQLite C library may be reached.
Mitigation
The vulnerability is fixed in rusqlite versions 0.25.4 and 0.26.2 [3][4]. Users should update to these versions. No workaround is available if updating is not feasible.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
rusqlitecrates.io | >= 0.25.0, < 0.25.4 | 0.25.4 |
rusqlitecrates.io | >= 0.26.0, < 0.26.2 | 0.26.2 |
Affected products
2- rust/rusqlitedescription
Patches
4f4f95f8caf9fBackport fix of closure lifetime issue to v0.25.x
4 files changed · +36 −36
Cargo.toml+1 −1 modified@@ -1,6 +1,6 @@ [package] name = "rusqlite" -version = "0.25.3" +version = "0.25.4" authors = ["The rusqlite developers"] edition = "2018" description = "Ergonomic wrapper for SQLite"
src/collation.rs+4 −4 modified@@ -16,9 +16,9 @@ unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) { impl Connection { /// `feature = "collation"` Add or modify a collation. #[inline] - pub fn create_collation<'c, C>(&'c self, collation_name: &str, x_compare: C) -> Result<()> + pub fn create_collation<C>(&self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, + C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, { self.db .borrow_mut() @@ -42,9 +42,9 @@ impl Connection { } impl InnerConnection { - fn create_collation<'c, C>(&'c mut self, collation_name: &str, x_compare: C) -> Result<()> + fn create_collation<C>(&mut self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, + C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, { unsafe extern "C" fn call_boxed_closure<C>( arg1: *mut c_void,
src/functions.rs+10 −10 modified@@ -379,15 +379,15 @@ impl Connection { /// /// Will return Err if the function could not be attached to the connection. #[inline] - pub fn create_scalar_function<'c, F, T>( - &'c self, + pub fn create_scalar_function<F, T>( + &self, fn_name: &str, n_arg: c_int, flags: FunctionFlags, x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, + F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, T: ToSql, { self.db @@ -411,7 +411,7 @@ impl Connection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - D: Aggregate<A, T>, + D: Aggregate<A, T> + 'static, T: ToSql, { self.db @@ -435,7 +435,7 @@ impl Connection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - W: WindowAggregate<A, T>, + W: WindowAggregate<A, T> + 'static, T: ToSql, { self.db @@ -460,15 +460,15 @@ impl Connection { } impl InnerConnection { - fn create_scalar_function<'c, F, T>( - &'c mut self, + fn create_scalar_function<F, T>( + &mut self, fn_name: &str, n_arg: c_int, flags: FunctionFlags, x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, + F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, T: ToSql, { unsafe extern "C" fn call_boxed_closure<F, T>( @@ -531,7 +531,7 @@ impl InnerConnection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - D: Aggregate<A, T>, + D: Aggregate<A, T> + 'static, T: ToSql, { let boxed_aggr: *mut D = Box::into_raw(Box::new(aggr)); @@ -562,7 +562,7 @@ impl InnerConnection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - W: WindowAggregate<A, T>, + W: WindowAggregate<A, T> + 'static, T: ToSql, { let boxed_aggr: *mut W = Box::into_raw(Box::new(aggr));
src/hooks.rs+21 −21 modified@@ -43,9 +43,9 @@ impl Connection { /// /// The callback returns `true` to rollback. #[inline] - pub fn commit_hook<'c, F>(&'c self, hook: Option<F>) + pub fn commit_hook<F>(&self, hook: Option<F>) where - F: FnMut() -> bool + Send + 'c, + F: FnMut() -> bool + Send + 'static, { self.db.borrow_mut().commit_hook(hook); } @@ -55,9 +55,9 @@ impl Connection { /// /// The callback returns `true` to rollback. #[inline] - pub fn rollback_hook<'c, F>(&'c self, hook: Option<F>) + pub fn rollback_hook<F>(&self, hook: Option<F>) where - F: FnMut() + Send + 'c, + F: FnMut() + Send + 'static, { self.db.borrow_mut().rollback_hook(hook); } @@ -73,9 +73,9 @@ impl Connection { /// - the name of the table that is updated, /// - the ROWID of the row that is updated. #[inline] - pub fn update_hook<'c, F>(&'c self, hook: Option<F>) + pub fn update_hook<F>(&self, hook: Option<F>) where - F: FnMut(Action, &str, &str, i64) + Send + 'c, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { self.db.borrow_mut().update_hook(hook); } @@ -105,9 +105,9 @@ impl InnerConnection { self.progress_handler(0, None::<fn() -> bool>); } - fn commit_hook<'c, F>(&'c mut self, hook: Option<F>) + fn commit_hook<F>(&mut self, hook: Option<F>) where - F: FnMut() -> bool + Send + 'c, + F: FnMut() -> bool + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) -> c_int where @@ -154,9 +154,9 @@ impl InnerConnection { self.free_commit_hook = free_commit_hook; } - fn rollback_hook<'c, F>(&'c mut self, hook: Option<F>) + fn rollback_hook<F>(&mut self, hook: Option<F>) where - F: FnMut() + Send + 'c, + F: FnMut() + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) where @@ -195,9 +195,9 @@ impl InnerConnection { self.free_rollback_hook = free_rollback_hook; } - fn update_hook<'c, F>(&'c mut self, hook: Option<F>) + fn update_hook<F>(&mut self, hook: Option<F>) where - F: FnMut(Action, &str, &str, i64) + Send + 'c, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>( p_arg: *mut c_void, @@ -313,13 +313,13 @@ mod test { fn test_commit_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.commit_hook(Some(|| { - called = true; + CALLED.store(true, Ordering::Relaxed); false })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) } @@ -341,30 +341,30 @@ mod test { fn test_rollback_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.rollback_hook(Some(|| { - called = true; + CALLED.store(true, Ordering::Relaxed); })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) } #[test] fn test_update_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.update_hook(Some(|action, db: &str, tbl: &str, row_id| { assert_eq!(Action::SQLITE_INSERT, action); assert_eq!("main", db); assert_eq!("foo", tbl); assert_eq!(1, row_id); - called = true; + CALLED.store(true, Ordering::Relaxed); })); db.execute_batch("CREATE TABLE foo (t TEXT)")?; db.execute_batch("INSERT INTO foo VALUES ('lisa')")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) }
1 file changed · +2 −2
src/functions.rs+2 −2 modified@@ -533,7 +533,7 @@ impl InnerConnection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - D: Aggregate<A, T>, + D: Aggregate<A, T> + 'static, T: ToSql, { let boxed_aggr: *mut D = Box::into_raw(Box::new(aggr)); @@ -564,7 +564,7 @@ impl InnerConnection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - W: WindowAggregate<A, T>, + W: WindowAggregate<A, T> + 'static, T: ToSql, { let boxed_aggr: *mut W = Box::into_raw(Box::new(aggr));
1 file changed · +2 −2
src/functions.rs+2 −2 modified@@ -412,7 +412,7 @@ impl Connection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - D: Aggregate<A, T>, + D: Aggregate<A, T> + 'static, T: ToSql, { self.db @@ -437,7 +437,7 @@ impl Connection { ) -> Result<()> where A: RefUnwindSafe + UnwindSafe, - W: WindowAggregate<A, T>, + W: WindowAggregate<A, T> + 'static, T: ToSql, { self.db
7 files changed · +56 −49
libsqlite3-sys/build.rs+4 −2 modified@@ -179,9 +179,11 @@ mod build_bundled { if cfg!(feature = "bundled-sqlcipher-vendored-openssl") { cfg.include(std::env::var("DEP_OPENSSL_INCLUDE").unwrap()); - // cargo will resolve downstream to the static lib in openssl-sys + // cargo will resolve downstream to the static lib in + // openssl-sys } else if is_windows { - // Windows without `-vendored-openssl` takes this to link against a prebuilt OpenSSL lib + // Windows without `-vendored-openssl` takes this to link against a prebuilt + // OpenSSL lib cfg.include(inc_dir.to_string_lossy().as_ref()); let lib = lib_dir.join("libcrypto.lib"); cfg.flag(lib.to_string_lossy().as_ref());
src/collation.rs+4 −4 modified@@ -16,9 +16,9 @@ unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) { impl Connection { /// Add or modify a collation. #[inline] - pub fn create_collation<'c, C>(&'c self, collation_name: &str, x_compare: C) -> Result<()> + pub fn create_collation<C>(&self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, + C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, { self.db .borrow_mut() @@ -42,9 +42,9 @@ impl Connection { } impl InnerConnection { - fn create_collation<'c, C>(&'c mut self, collation_name: &str, x_compare: C) -> Result<()> + fn create_collation<C>(&mut self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, + C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, { unsafe extern "C" fn call_boxed_closure<C>( arg1: *mut c_void,
src/functions.rs+6 −6 modified@@ -380,15 +380,15 @@ impl Connection { /// /// Will return Err if the function could not be attached to the connection. #[inline] - pub fn create_scalar_function<'c, F, T>( - &'c self, + pub fn create_scalar_function<F, T>( + &self, fn_name: &str, n_arg: c_int, flags: FunctionFlags, x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, + F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, T: ToSql, { self.db @@ -462,15 +462,15 @@ impl Connection { } impl InnerConnection { - fn create_scalar_function<'c, F, T>( - &'c mut self, + fn create_scalar_function<F, T>( + &mut self, fn_name: &str, n_arg: c_int, flags: FunctionFlags, x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'c, + F: FnMut(&Context<'_>) -> Result<T> + Send + UnwindSafe + 'static, T: ToSql, { unsafe extern "C" fn call_boxed_closure<F, T>(
src/hooks.rs+21 −21 modified@@ -345,9 +345,9 @@ impl Connection { /// /// The callback returns `true` to rollback. #[inline] - pub fn commit_hook<'c, F>(&'c self, hook: Option<F>) + pub fn commit_hook<F>(&self, hook: Option<F>) where - F: FnMut() -> bool + Send + 'c, + F: FnMut() -> bool + Send + 'static, { self.db.borrow_mut().commit_hook(hook); } @@ -357,9 +357,9 @@ impl Connection { /// /// The callback returns `true` to rollback. #[inline] - pub fn rollback_hook<'c, F>(&'c self, hook: Option<F>) + pub fn rollback_hook<F>(&self, hook: Option<F>) where - F: FnMut() + Send + 'c, + F: FnMut() + Send + 'static, { self.db.borrow_mut().rollback_hook(hook); } @@ -375,9 +375,9 @@ impl Connection { /// - the name of the table that is updated, /// - the ROWID of the row that is updated. #[inline] - pub fn update_hook<'c, F>(&'c self, hook: Option<F>) + pub fn update_hook<F>(&self, hook: Option<F>) where - F: FnMut(Action, &str, &str, i64) + Send + 'c, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { self.db.borrow_mut().update_hook(hook); } @@ -418,9 +418,9 @@ impl InnerConnection { self.authorizer(None::<fn(AuthContext<'_>) -> Authorization>); } - fn commit_hook<'c, F>(&'c mut self, hook: Option<F>) + fn commit_hook<F>(&mut self, hook: Option<F>) where - F: FnMut() -> bool + Send + 'c, + F: FnMut() -> bool + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) -> c_int where @@ -467,9 +467,9 @@ impl InnerConnection { self.free_commit_hook = free_commit_hook; } - fn rollback_hook<'c, F>(&'c mut self, hook: Option<F>) + fn rollback_hook<F>(&mut self, hook: Option<F>) where - F: FnMut() + Send + 'c, + F: FnMut() + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>(p_arg: *mut c_void) where @@ -508,9 +508,9 @@ impl InnerConnection { self.free_rollback_hook = free_rollback_hook; } - fn update_hook<'c, F>(&'c mut self, hook: Option<F>) + fn update_hook<F>(&mut self, hook: Option<F>) where - F: FnMut(Action, &str, &str, i64) + Send + 'c, + F: FnMut(Action, &str, &str, i64) + Send + 'static, { unsafe extern "C" fn call_boxed_closure<F>( p_arg: *mut c_void, @@ -698,13 +698,13 @@ mod test { fn test_commit_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.commit_hook(Some(|| { - called = true; + CALLED.store(true, Ordering::Relaxed); false })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) } @@ -726,30 +726,30 @@ mod test { fn test_rollback_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.rollback_hook(Some(|| { - called = true; + CALLED.store(true, Ordering::Relaxed); })); db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) } #[test] fn test_update_hook() -> Result<()> { let db = Connection::open_in_memory()?; - let mut called = false; + static CALLED: AtomicBool = AtomicBool::new(false); db.update_hook(Some(|action, db: &str, tbl: &str, row_id| { assert_eq!(Action::SQLITE_INSERT, action); assert_eq!("main", db); assert_eq!("foo", tbl); assert_eq!(1, row_id); - called = true; + CALLED.store(true, Ordering::Relaxed); })); db.execute_batch("CREATE TABLE foo (t TEXT)")?; db.execute_batch("INSERT INTO foo VALUES ('lisa')")?; - assert!(called); + assert!(CALLED.load(Ordering::Relaxed)); Ok(()) }
src/lib.rs+15 −9 modified@@ -159,9 +159,11 @@ pub const NO_PARAMS: &[&dyn ToSql] = &[]; /// } /// /// fn add_person(conn: &Connection, person: &Person) -> Result<()> { -/// conn.execute("INSERT INTO person (name, age_in_years, data) +/// conn.execute( +/// "INSERT INTO person (name, age_in_years, data) /// VALUES (?1, ?2, ?3)", -/// params![person.name, person.age_in_years, person.data])?; +/// params![person.name, person.age_in_years, person.data], +/// )?; /// Ok(()) /// } /// ``` @@ -193,11 +195,11 @@ macro_rules! params { /// conn.execute( /// "INSERT INTO person (name, age_in_years, data) /// VALUES (:name, :age, :data)", -/// named_params!{ +/// named_params! { /// ":name": person.name, /// ":age": person.age_in_years, /// ":data": person.data, -/// } +/// }, /// )?; /// Ok(()) /// } @@ -462,10 +464,11 @@ impl Connection { /// ```rust,no_run /// # use rusqlite::{Connection, Result}; /// fn create_tables(conn: &Connection) -> Result<()> { - /// conn.execute_batch("BEGIN; - /// CREATE TABLE foo(x INTEGER); - /// CREATE TABLE bar(y TEXT); - /// COMMIT;", + /// conn.execute_batch( + /// "BEGIN; + /// CREATE TABLE foo(x INTEGER); + /// CREATE TABLE bar(y TEXT); + /// COMMIT;", /// ) /// } /// ``` @@ -515,7 +518,10 @@ impl Connection { /// ```rust,no_run /// # use rusqlite::{params, Connection}; /// fn update_rows(conn: &Connection) { - /// match conn.execute("UPDATE foo SET bar = 'baz' WHERE qux = ?1 AND quux = ?2", params![1i32, 1.5f64]) { + /// match conn.execute( + /// "UPDATE foo SET bar = 'baz' WHERE qux = ?1 AND quux = ?2", + /// params![1i32, 1.5f64], + /// ) { /// Ok(updated) => println!("{} rows were updated", updated), /// Err(err) => println!("update failed: {}", err), /// }
src/params.rs+2 −2 modified@@ -116,7 +116,7 @@ use sealed::Sealed; /// fn insert(conn: &Connection) -> Result<()> { /// let mut stmt = conn.prepare("INSERT INTO test (key, value) VALUES (:key, :value)")?; /// // Using `rusqlite::params!`: -/// stmt.execute(named_params!{ ":key": "one", ":val": 2 })?; +/// stmt.execute(named_params! { ":key": "one", ":val": 2 })?; /// // Alternatively: /// stmt.execute(&[(":key", "three"), (":val", "four")])?; /// // Or: @@ -251,7 +251,7 @@ impl_for_array_ref!( /// ## Basic usage /// /// ```rust,no_run -/// use rusqlite::{Connection, Result, params_from_iter}; +/// use rusqlite::{params_from_iter, Connection, Result}; /// use std::collections::BTreeSet; /// /// fn query(conn: &Connection, ids: &BTreeSet<String>) -> Result<()> {
src/statement.rs+4 −5 modified@@ -55,7 +55,7 @@ impl Statement<'_> { /// // The `rusqlite::named_params!` macro (like `params!`) is useful for heterogeneous /// // sets of parameters (where all parameters are not the same type), or for queries /// // with many (more than 32) statically known parameters. - /// stmt.execute(named_params!{ ":key": "one", ":val": 2 })?; + /// stmt.execute(named_params! { ":key": "one", ":val": 2 })?; /// // However, named parameters can also be passed like: /// stmt.execute(&[(":key", "three"), (":val", "four")])?; /// // Or even: (note that a &T is required for the value type, currently) @@ -208,7 +208,7 @@ impl Statement<'_> { /// # use rusqlite::{Connection, Result, named_params}; /// fn query(conn: &Connection) -> Result<()> { /// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?; - /// let mut rows = stmt.query(named_params!{ ":name": "one" })?; + /// let mut rows = stmt.query(named_params! { ":name": "one" })?; /// while let Some(row) = rows.next()? { /// // ... /// } @@ -346,13 +346,12 @@ impl Statement<'_> { /// /// fn name_to_person(name: String) -> Result<Person> { /// // ... check for valid name - /// Ok(Person { name: name }) + /// Ok(Person { name }) /// } /// /// fn get_names(conn: &Connection) -> Result<Vec<Person>> { /// let mut stmt = conn.prepare("SELECT name FROM people WHERE id = :id")?; - /// let rows = - /// stmt.query_and_then(&[(":id", "one")], |row| name_to_person(row.get(0)?))?; + /// let rows = stmt.query_and_then(&[(":id", "one")], |row| name_to_person(row.get(0)?))?; /// /// let mut persons = Vec::new(); /// for person_result in rows {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-92cx-4xm7-jr9mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-45713ghsaADVISORY
- github.com/rusqlite/rusqlite/commit/30f8c8c502675011603c4d066396bf317fd49e71ghsaWEB
- github.com/rusqlite/rusqlite/commit/612158507e90f41d409cd0fa80eb21c992b1bc08ghsaWEB
- github.com/rusqlite/rusqlite/commit/934e0c709e156753881da98b32e9853f9ffe4a1bghsaWEB
- github.com/rusqlite/rusqlite/commit/f4f95f8caf9fd53bffd0c19530be2484c644cc16ghsaWEB
- github.com/rusqlite/rusqlite/issues/1048ghsaWEB
- github.com/rusqlite/rusqlite/pull/1049ghsaWEB
- raw.githubusercontent.com/rustsec/advisory-db/main/crates/rusqlite/RUSTSEC-2021-0128.mdghsax_refsource_MISCWEB
- rustsec.org/advisories/RUSTSEC-2021-0128.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.