1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-35738 mariadb build -fsanitize=pointer-compare

invalid pointer pairs are when the length/memory of one string are
intermixed with another.

For comp_err, the end null pointer was compared to soffset within
my_strtoll10. As we didn't need the end position a NULL arg option
was compatble.

For uca-dump, Address Sanitizer raises invalid pointer pair because
argv options (opt) don't have an obvious correlation of having a start
at opt_X.length, even though the lstrncmp makes this true.

The DBUG_ASSERTS of strmov (added MDEV-11752) where incompatible with
pointer-compare. Replaced strmov with static inline version in
m_string.h using memmove that allows overlaps, and being inline allows
the uneeded parts of the implementation to be optimized away.
This commit is contained in:
Daniel Black
2026-05-03 09:44:30 +10:00
parent 8370daf768
commit d3afdd162b
5 changed files with 29 additions and 60 deletions

View File

@@ -623,7 +623,7 @@ static uint parse_input_file(const char *file_name, struct errors **top_error,
static uint parse_error_offset(char *str)
{
char *soffset, *end;
char *soffset;
int error;
uint ioffset;
@@ -651,8 +651,7 @@ static uint parse_error_offset(char *str)
}
DBUG_PRINT("info", ("str: %s", str));
end= 0;
ioffset= (uint) my_strtoll10(soffset, &end, &error);
ioffset= (uint) my_strtoll10(soffset, NULL, &error);
my_free(soffset);
DBUG_RETURN(ioffset);
}

View File

@@ -65,13 +65,23 @@
extern "C" {
#endif
#ifdef DBUG_OFF
#if defined(HAVE_STPCPY) && defined(__GNUC__) && !defined(__INTEL_COMPILER)
#define strmov(A,B) __builtin_stpcpy((A),(B))
#elif defined(HAVE_STPCPY)
#define strmov(A,B) stpcpy((A),(B))
#endif
#endif
#else
__attribute__((nonnull))
static inline char *strmov(char *dst, const char *src)
{
size_t l;
DBUG_ASSERT(dst != NULL);
DBUG_ASSERT(src != NULL);
l= strlen(src);
memmove(dst, src, l + 1);
return dst + l;
}
#endif /* strmov */
/* Declared in int2str() */
extern const char _dig_vec_upper[];

View File

@@ -24,7 +24,7 @@ SET(STRINGS_SOURCES bchange.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c dtoa.c int2str.c
ctype-unidata.c
is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c
str2int.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
str2int.c strcend.c strend.c strfill.c strmake.c strnmov.c
strxmov.c strxnmov.c xml.c
strmov_overlapp.c
my_strchr.c strcont.c strappend.c json_lib.c json_normalize.c)

View File

@@ -1,48 +0,0 @@
/* Copyright (c) 2000 TXT DataKonsult Ab & Monty Program Ab
Copyright (c) 2009-2011, Monty Program Ab
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
strmov(dst, src) moves all the characters of src (including the
closing NUL) to dst, and returns a pointer to the new closing NUL in
dst. The similar UNIX routine strcpy returns the old value of dst,
which I have never found useful. strmov(strmov(dst,a),b) moves a//b
into dst, which seems useful.
*/
#include "strings_def.h"
#ifndef strmov
char *strmov(register char *dst, register const char *src)
{
DBUG_ASSERT(src + strlen(src) < dst || dst + strlen(src) < src);
while ((*dst++ = *src++)) ;
return dst-1;
}
#endif /* strmov */

View File

@@ -417,14 +417,20 @@ static int process_option(OPT *options, const char *opt)
static const LEX_CSTRING opt_levels= {STRING_WITH_LEN("--levels=")};
static const LEX_CSTRING opt_no_contractions= {STRING_WITH_LEN("--no-contractions")};
static const LEX_CSTRING opt_case_first= {STRING_WITH_LEN("--case-first=")};
const char *eq= strchr(opt, '=');
if (!lstrncmp(opt, opt_name_prefix))
{
options->name_prefix= opt + opt_name_prefix.length;
if (!eq)
return 1;
options->name_prefix= eq + 1;
return 0;
}
if (!lstrncmp(opt, opt_levels))
{
options->levels= (uint) strtoul(opt + opt_levels.length, NULL, 10);
if (!eq)
return 1;
options->levels= (uint) strtoul(eq + 1, NULL, 10);
if (options->levels < 1 || options->levels > 3)
{
printf("Bad --levels value\n");
@@ -434,13 +440,15 @@ static int process_option(OPT *options, const char *opt)
}
if (!lstrncmp(opt, opt_case_first))
{
const char *value= opt + opt_case_first.length;
if (!strcasecmp(value, "upper"))
if (!eq)
return 1;
eq++;
if (!strcasecmp(eq, "upper"))
{
options->case_first_upper= TRUE;
return 0;
}
if (!strcasecmp(value, "lower"))
if (!strcasecmp(eq, "lower"))
{
options->case_first_upper= FALSE;
return 0;