GHSA-ff9q-rm55-q7qr: Diesel async Diesel-async May Expose Uninitialized Padding Vulnerability
LOWGHSA-ff9q-rm55-q7qr is a LOW diesel-async may expose uninitialized padding vulnerability (CWE-126: Buffer Over-read) affecting Diesel async libraries in the crates.io ecosystem. The issue involves diesel-async may expose uninitialized padding bytes for mysql temporal columns. Remediation is available by upgrading affected packages to version 0.9.0.
GHSA-ff9q-rm55-q7qr at a Glance
How to Fix GHSA-ff9q-rm55-q7qr
To remediate this vulnerability, upgrade all affected Diesel async dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade diesel-async to 0.9.0
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for diesel-async
How to Check if You Are Affected
To determine whether your application is affected by GHSA-ff9q-rm55-q7qr, inspect your project dependencies for Diesel async:
inspect dependencies for diesel-async
Analyze the terminal output to locate any version of Diesel async in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.9.0), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-126: Buffer Over-read, where the product reads from a buffer using buffer access mechanisms such as indexes or pointers that reference memory locations after the targeted buffer. In Diesel async, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-ff9q-rm55-q7qr Affected Diesel async Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
diesel-async
|
crates.io |
≥ 0.1.0
< 0.9.0
|
0.9.0
|
References
Frequently Asked Questions
What is GHSA-ff9q-rm55-q7qr?
Which Diesel async versions are affected?
What version fixes GHSA-ff9q-rm55-q7qr?
Is diesel-async affected?
What CWE is associated with GHSA-ff9q-rm55-q7qr?
How can I check crates.io dependencies for GHSA-ff9q-rm55-q7qr?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-ff9q-rm55-q7qr",
"modified" : "2026-05-07T00:02:22Z",
"published" : "2026-05-07T00:02:22Z",
"aliases" : [ ],
"summary" : "diesel-async may expose uninitialized padding bytes for MySQL temporal columns",
"details" : "### Summary\n\ndiesel-async exposes uninitialized stack padding to safe code on every read of a MySQL `DATE`, `TIME`, `DATETIME`, or `TIMESTAMP` column. Reading that buffer is undefined behavior, and the leaked bytes can contain stale heap/stack contents, so this is both a soundness bug and a potential information-disclosure vector.\n\n### Details\n\nIn `diesel-async/src/mysql/row.rs` (lines 65-103), `MysqlRow::get` builds a `MysqlTime` from the parsed `mysql_async::Value` and then fabricates the byte buffer that downstream `FromSql` impls expect like this:\n\n```rust\nlet date = MysqlTime::new(/* fields from Value::Date / Value::Time */);\nlet buffer = unsafe {\n let ptr = &date as *const MysqlTime as *const u8;\n let slice = std::slice::from_raw_parts(ptr, std::mem::size_of::<MysqlTime>());\n slice.to_vec()\n};\n```\n\n`MysqlTime` is `#[repr(C)]` with 3 bytes of padding after `bool neg` (Linux x86_64, offsets 0x21..0x23). The literal construction leaves that padding uninitialized, and `to_vec()` carries it into a `Vec<u8>` that becomes the `MysqlValue`'s backing buffer, reachable from safe code via `MysqlValue::as_bytes() -> &[u8]`.\n\n`diesel` itself avoids this by going through `MaybeUninit::<MysqlTime>::zeroed()` + `ptr::copy_nonoverlapping` (see `diesel/src/mysql/value.rs:43-94`); the same pattern would fix this. Alternatively, write the bytes diesel's `FromSql` reads without round-tripping through a `MysqlTime` value.\n\n### PoC\n\n`Cargo.toml`:\n```toml\n[dependencies]\ndiesel = { version = \"~2.3.0\", default-features = false, features = [\"mysql_backend\"] }\ndiesel-async = { version = \"=0.8.0\", features = [\"mysql\"] }\nmysql_common = { version = \"0.35\", default-features = false }\n```\n\n`src/main.rs`:\n```rust\nuse diesel::row::{Field, Row};\nuse diesel_async::{AsyncConnectionCore, AsyncMysqlConnection};\nuse mysql_common::{constants::ColumnType, packets::Column, prelude::FromRow, value::Value};\n\ntype MysqlRow = <AsyncMysqlConnection as AsyncConnectionCore>::Row<'static, 'static>;\n\nfn main() {\n let cols = std::sync::Arc::from([Column::new(ColumnType::MYSQL_TYPE_DATE)]);\n let raw = mysql_common::row::new_row(vec![Value::Date(2024, 1, 1, 0, 0, 0, 0)], cols);\n let row: MysqlRow = FromRow::from_row(raw);\n\n let field = row.get(0).unwrap();\n let bytes = field.value().unwrap().as_bytes();\n let _: u64 = bytes.iter().map(|&b| b as u64).sum(); // UB: hits padding\n}\n```\n\nMiri output:\n\n```\nerror: Undefined Behavior: reading memory at alloc844[0x21..0x22], but memory is uninitialized at [0x21..0x22], and this operation requires initialized memory\n --> src/main.rs:14:37\n |\n14 | let _: u64 = bytes.iter().map(|&b| b as u64).sum(); // UB: hits padding\n | ^ Undefined Behavior occurred here\n |\n = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior\n = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information\n = note: stack backtrace:\n 0: main::{closure#0}\n at src/main.rs:14:37: 14:38\n 1: std::iter::adapters::map::map_fold::<&u8, u64, u64, {closure@src/main.rs:14:35: 14:39}, {closure@<u64 as std::iter::Sum>::sum<std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}>>::{closure#0}}>::{closure#0}\n at /home/paolobarbolini/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:88:28: 88:34\n 2: <std::slice::Iter<'_, u8> as std::iter::Iterator>::fold::<u64, {closure@std::iter::adapters::map::map_fold<&u8, u64, u64, {closure@src/main.rs:14:35: 14:39}, {closure@<u64 as std::iter::Sum>::sum<std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}>>::{closure#0}}>::{closure#0}}>\n at /home/paolobarbolini/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/iter/macros.rs:279:27: 279:85\n 3: <std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}> as std::iter::Iterator>::fold::<u64, {closure@<u64 as std::iter::Sum>::sum<std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}>>::{closure#0}}>\n at /home/paolobarbolini/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:128:9: 128:50\n 4: <u64 as std::iter::Sum>::sum::<std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}>>\n at /home/paolobarbolini/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/accum.rs:52:17: 56:18\n 5: <std::iter::Map<std::slice::Iter<'_, u8>, {closure@src/main.rs:14:35: 14:39}> as std::iter::Iterator>::sum::<u64>\n at /home/paolobarbolini/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3676:9: 3676:23\n 6: main\n at src/main.rs:14:18: 14:55\n\nUninitialized memory occurred at alloc844[0x21..0x22], in this allocation:\nalloc844 (Rust heap, size: 48, align: 1) {\n 0x00 │ e8 07 00 00 01 00 00 00 01 00 00 00 00 00 00 00 │ ................\n 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................\n 0x20 │ 00 __ __ __ 01 00 00 00 00 00 00 00 __ __ __ __ │ .░░░........░░░░\n}\n```\n\n### Impact\n\nSoundness bug in safe API surface of `diesel-async`'s MySQL backend. Affects every user of `AsyncMysqlConnection` whose queries return a temporal column.\n\nAI disclosure: this issue was found via Claude Code running Claude Opus 4.7.",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N/E:P"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "crates.io",
"name" : "diesel-async"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0.1.0"
}, {
"fixed" : "0.9.0"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/diesel-rs/diesel_async/security/advisories/GHSA-ff9q-rm55-q7qr"
}, {
"type" : "WEB",
"url" : "https://github.com/diesel-rs/diesel_async/commit/18f2c861c51b4a5f23a20bd749eba13737b9e4aa"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/diesel-rs/diesel_async"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-126" ],
"severity" : "LOW",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-07T00:02:22Z",
"nvd_published_at" : null
}
}