MDEV-35620 UBSAN: runtime error: applying zero offset to null pointer

in _ma_unique_hash, skip_trailing_space, my_hash_sort_mb_nopad_bin and my_strnncollsp_utf8mb4_bin

UBSAN detected the nullptr-with-offset in a few places
when handling empty blobs.

Fix:
- Adding DBUG_ASSERT(source_string) into all hash_sort() implementations
  to catch this problem in non-UBSAN debug builds.
- Fixing mi_unique_hash(), mi_unique_comp(),
  _ma_unique_hash(), _ma_unique_comp() to replace NULL pointer to
  an empty string ponter..

Note, we should also add DBUG_ASSERT(source_string != NULL) into
all implementations of strnncoll*(). But I'm afraid the patch
is going to be too long and too dangerous for 10.5.
This commit is contained in:
Alexander Barkov 2025-02-03 15:00:35 +04:00
commit 583b39811c
13 changed files with 81 additions and 3 deletions

View file

@ -139,6 +139,8 @@ ha_checksum _ma_unique_hash(MARIA_UNIQUEDEF *def, const uchar *record)
{
uint tmp_length= _ma_calc_blob_length(keyseg->bit_start,pos);
memcpy((void*) &pos,pos+keyseg->bit_start,sizeof(char*));
if (!pos)
pos= (const uchar*) ""; /* hash_sort does not support NULL ptr */
if (!length || length > tmp_length)
length=tmp_length; /* The whole blob */
}
@ -236,6 +238,10 @@ my_bool _ma_unique_comp(MARIA_UNIQUEDEF *def, const uchar *a, const uchar *b,
}
memcpy((void*) &pos_a, pos_a+keyseg->bit_start, sizeof(char*));
memcpy((void*) &pos_b, pos_b+keyseg->bit_start, sizeof(char*));
if (pos_a == 0)
pos_a= (const uchar *) ""; /* Avoid UBSAN nullptr-with-offset */
if (pos_b == 0)
pos_b= (const uchar *) ""; /* Avoid UBSAN nullptr-with-offset */
}
if (type == HA_KEYTYPE_TEXT/* the CHAR data type*/)
{

View file

@ -115,6 +115,8 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const uchar *record)
{
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
memcpy((char**) &pos, pos+keyseg->bit_start, sizeof(char*));
if (!pos)
pos= (const uchar*) ""; /* hash_sort does not support NULL ptr */
if (!length || length > tmp_length)
length=tmp_length; /* The whole blob */
}
@ -211,6 +213,10 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const uchar *a, const uchar *b,
}
memcpy((char**) &pos_a, pos_a+keyseg->bit_start, sizeof(char*));
memcpy((char**) &pos_b, pos_b+keyseg->bit_start, sizeof(char*));
if (pos_a == 0)
pos_a= (const uchar *) ""; /* Avoid UBSAN nullptr-with-offset */
if (pos_b == 0)
pos_b= (const uchar *) ""; /* Avoid UBSAN nullptr-with-offset */
}
if (type == HA_KEYTYPE_TEXT/*The CHAR data type*/)
{