Skip to content

MDEV-35715: UBSAN: runtime error: 1e+19 is outside the range of representable values of type 'long long' in Field_bit::store on INSERT#5081

Draft
kjarir wants to merge 1 commit into
MariaDB:mainfrom
kjarir:MDEV-35715-fix-10.11
Draft

MDEV-35715: UBSAN: runtime error: 1e+19 is outside the range of representable values of type 'long long' in Field_bit::store on INSERT#5081
kjarir wants to merge 1 commit into
MariaDB:mainfrom
kjarir:MDEV-35715-fix-10.11

Conversation

@kjarir
Copy link
Copy Markdown
Contributor

@kjarir kjarir commented May 15, 2026

When a floating-point value (e.g., 1e+19 or -1e+30) that is outside the representable range of a 64-bit integer type is cast directly via (longlong) nr or (ulonglong) nr, C++ produces Undefined Behavior (UB). UndefinedBehaviorSanitizer (UBSAN) flags this during runtime as a float-cast-overflow.

This directly affected:

  • Field_bit::store(double)
  • Field_enum::store(double)
  • Field_set::store(double) (inlined to Field_enum::store)

Solution

Replaced the direct C-style (longlong) casts with MariaDB's standard Converter_double_to_longlong helper class.

Instead of an unsafe cast, the converter safely rounds and clamps out-of-bounds double values to their respective integer minimums/maximums (ULLONG_MAX, LLONG_MAX, or LLONG_MIN depending on the explicit unsigned_flag) before proceeding with the normal truncation logic. This replicates the exact behavior existing in other numeric store(double) methods, maintaining the same warning outputs (ER_WARN_DATA_OUT_OF_RANGE / WARN_DATA_TRUNCATED) while completely eliminating the Undefined Behavior.

Testing

  • Added MTR test main.type_bit_mdev35715 validating BIT, ENUM, and SET overflow boundaries.
  • Verified test suite passes without producing UBSAN runtime errors for the affected types.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 15, 2026

CLA assistant check
All committers have signed the CLA.

@kjarir kjarir force-pushed the MDEV-35715-fix-10.11 branch from ae4413f to c20fff0 Compare May 15, 2026 15:38
…(double)

Casting a double like 1e19 directly to longlong is UB when the value
is outside [-2^63, 2^63-1]. Clamp before the cast, same way other
numeric store() methods already do.
@kjarir kjarir force-pushed the MDEV-35715-fix-10.11 branch from c20fff0 to a6268f5 Compare May 15, 2026 15:40
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request performs extensive security hardening and bug fixes, notably replacing sprintf with snprintf across the codebase and the CONNECT storage engine to prevent buffer overflows. Key enhancements include strict numeric validation for master.info, LENENC support for long passwords in COM_CHANGE_USER, and improved handling of negative zero in floating-point storage. It also resolves various crash scenarios in GIS and JSON functions, memory leaks, and replication inconsistencies. Review feedback identified a critical type mismatch in sql/wsrep_applier.cc that could lead to undefined behavior during debug logging, and a potential stack buffer overflow in sql/mysqld.cc when handling Unix socket paths.

I am having trouble creating individual review comments. Click here to see my feedback.

sql/wsrep_applier.cc (103-104)

high

The change from a byte buffer to a std::vectorstd::string (implied by push_back(err_str)) seems to conflict with the subsequent WSREP_DEBUG call (line 106-108 in context) which uses dst.data() with a %s format specifier. If dst is now a vector of strings, dst.data() returns a std::string*, which will cause Undefined Behavior or a crash when passed to %s. Please ensure the debug print is updated to access the string content correctly, e.g., dst.empty() ? "" : dst[0].c_str().

sql/mysqld.cc (2707)

security-medium medium

The use of strmov to copy path into addr.sun_path is potentially dangerous if path exceeds the fixed size of the sun_path array (typically 108 bytes). While there is a length check later in network_init, this utility function should ideally be self-protecting. Consider using strmake or adding an explicit length check before the copy to prevent a stack buffer overflow.

  if (strlen(path) >= sizeof(addr.sun_path))
  {
    sql_print_error("Unix socket path is too long: %s", path);
    unireg_abort(1);
  }
  strmov(addr.sun_path, path);

@grooverdan grooverdan self-assigned this May 16, 2026
@grooverdan grooverdan marked this pull request as draft May 16, 2026 01:16
@grooverdan
Copy link
Copy Markdown
Member

Lets get a working local test environment so mtr matches results before submitting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants