Details
-
Bug
-
Status: Open (View Workflow)
-
Minor
-
Resolution: Unresolved
-
None
-
None
-
None
-
None
Description
[use of codex (AI) was relied on to diagnose the issue via github actions with windows builds and to try and identify relevant source code; apologies if this report ends up not being helpful, but I tried my best to be the human in the loop and reviewing all diagnoses and suggestions]
Summary
MariaDB Connector/C 3.4.9 can crash on Windows during prepared statement execution in ma_stmt_execute_generate_simple_request when built with MinGW GCC optimizations. The crash appears to be caused by the Windows/x86 fast-path int2store macro storing through a typed uint16* into a protocol packet byte buffer whose current offset is not guaranteed to satisfy that store's alignment assumptions. GCC's vectorizer can then combine the repeated type writes into aligned SSE stores, producing a faulting movaps instruction on Windows.
This looks less like a confirmed GCC miscompilation and more like Connector/C relying on undefined behavior / unsafe alignment assumptions that a particular optimized build exposes.
Affected version
- MariaDB Connector/C 3.4.9 source
- Windows builds produced by JuliaPackaging/Yggdrasil's MinGW toolchain
- The official MariaDB Connector/C 3.4.9 Windows DLL did not reproduce the crash in our diagnostics, likely because that build does not emit the same vectorized aligned-store sequence.
Symptoms
Using JuliaDatabases/MySQL.jl with MariaDB_Connector_C_jll 3.4.9+0 on Windows, prepared statement execution crashes with:
EXCEPTION_ACCESS_VIOLATION
|
ma_stmt_execute_generate_simple_request
|
The failing Yggdrasil-built DLL contains a faulting aligned SSE store in ma_stmt_execute_generate_simple_request:
movaps xmmword ptr [r11 - 0x10], xmm0
|
Relevant source locations
In include/ma_global.h, the Windows/x86 branch uses typed stores for little-endian integer writes:
#if defined(__i386__) || defined(_WIN32)
|
...
|
#define int2store(T,A) *((uint16*) (T))= (uint16) (A) |
Current 3.4 branch reference:
https://github.com/mariadb-corporation/mariadb-connector-c/blob/3.4/include/ma_global.h#L744-L783
In libmariadb/mariadb_stmt.c, ma_stmt_execute_generate_simple_request allocates a byte buffer and writes the prepared-statement packet. The parameter type loop writes 2 bytes per parameter:
if (!(start= p= (uchar *)malloc(length))) |
goto mem_error; |
|
|
int4store(p, stmt->stmt_id);
|
p += STMT_ID_LENGTH;
|
|
|
int1store(p, (unsigned char) stmt->flags); |
p++;
|
|
|
int4store(p, 1);
|
p+= 4;
|
|
|
...
|
|
|
size_t null_count= (stmt->param_count + 7) / 8; |
...
|
p += null_count;
|
|
|
int1store(p, stmt->send_types_to_server);
|
p++;
|
|
|
...
|
|
|
for (i = 0; i < stmt->param_count; i++) |
{
|
uint buffer_type= stmt->params[i].buffer_type | (stmt->params[i].is_unsigned ? 32768 : 0);
|
int2store(p, buffer_type);
|
p+= 2;
|
}
|
Current 3.4 branch reference:
https://github.com/mariadb-corporation/mariadb-connector-c/blob/3.4/libmariadb/mariadb_stmt.c#L772-L828
For example, with 33 parameters, null_count = (33 + 7) / 8 = 5. The type-info pointer starts at malloc_base + 4 + 1 + 4 + 5 + 1 = malloc_base + 15, so the int2store loop starts from an odd byte offset. The macro casts that uchar* to uint16* and stores through it.
Diagnostics performed
In JuliaDatabases/MySQL.jl diagnostics:
- Released MariaDB_Connector_C_jll 3.4.9+0 crashed on both windows-2022 and windows-2025 GitHub Actions images.
- Official MariaDB Connector/C 3.4.9 Windows DLL passed on both Windows images.
- Older MariaDB_Connector_C_jll 3.3.9 passed.
- A Yggdrasil rebuild of Connector/C 3.4.9 with -fno-tree-vectorize passed on both Windows images.
- Disassembly of the failing JLL showed the faulting movaps inside ma_stmt_execute_generate_simple_request; the -fno-tree-vectorize rebuild did not contain the vectorized movaps store sequence in that function.
Diagnostic run:
https://github.com/JuliaDatabases/MySQL.jl/actions/runs/27571414885
Original downstream issue:
https://github.com/JuliaDatabases/MySQL.jl/issues/236
Yggdrasil workaround PR:
https://github.com/JuliaPackaging/Yggdrasil/pull/13971
Suggested upstream fix
Avoid typed stores through potentially unaligned packet-buffer pointers in this path. Possible fixes include:
- Make the Windows/x86 int2store implementation byte-wise, like the non-x86 fallback.
- Use memcpy for the 2-byte store.
- Use a byte-wise helper specifically for protocol packet construction.
Julia's binary build is using -fno-tree-vectorize as a downstream workaround, but the root issue appears to be that Connector/C's packet buffer writes do not satisfy the alignment assumptions introduced by the typed uint16* store.
Attachments
Issue Links
- relates to
-
MDEV-37788 fix uintNkorr in byte_order_generic.h, avoid unaligned access
-
- Closed
-