MDEV-24841 Build error with MSAN use-of-uninitialized-value in comp_err
The MemorySanitizer implementation in clang includes some built-in instrumentation (interceptors) for GNU libc. In GNU libc 2.33, the interface to the stat() family of functions was changed. Until the MemorySanitizer interceptors are adjusted, any MSAN code builds will act as if that the stat() family of functions failed to initialize the struct stat. A fix was applied in https://reviews.llvm.org/rG4e1a6c07052b466a2a1cd0c3ff150e4e89a6d87a but it fails to cover the 64-bit variants of the calls. For now, let us work around the MemorySanitizer bug by defining and using the macro MSAN_STAT_WORKAROUND().
This commit is contained in:
parent
d78173828e
commit
59359fb44a
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2010, 2020, MariaDB Corporation.
|
/* Copyright (C) 2010, 2022, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -37,6 +37,11 @@
|
|||||||
# define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len)
|
# define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len)
|
||||||
# define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len)
|
# define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len)
|
||||||
# define REDZONE_SIZE 8
|
# define REDZONE_SIZE 8
|
||||||
|
# ifdef __linux__
|
||||||
|
# define MSAN_STAT_WORKAROUND(st) MEM_MAKE_DEFINED(st, sizeof(*st))
|
||||||
|
# else
|
||||||
|
# define MSAN_STAT_WORKAROUND(st) ((void) 0)
|
||||||
|
# endif
|
||||||
#elif defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind)
|
#elif defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind)
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
# define HAVE_MEM_CHECK
|
# define HAVE_MEM_CHECK
|
||||||
@ -49,6 +54,7 @@
|
|||||||
# define MEM_GET_VBITS(a,b,len) VALGRIND_GET_VBITS(a,b,len)
|
# define MEM_GET_VBITS(a,b,len) VALGRIND_GET_VBITS(a,b,len)
|
||||||
# define MEM_SET_VBITS(a,b,len) VALGRIND_SET_VBITS(a,b,len)
|
# define MEM_SET_VBITS(a,b,len) VALGRIND_SET_VBITS(a,b,len)
|
||||||
# define REDZONE_SIZE 8
|
# define REDZONE_SIZE 8
|
||||||
|
# define MSAN_STAT_WORKAROUND(st) ((void) 0)
|
||||||
#elif defined(__SANITIZE_ADDRESS__) && (!defined(_MSC_VER) || defined (__clang__))
|
#elif defined(__SANITIZE_ADDRESS__) && (!defined(_MSC_VER) || defined (__clang__))
|
||||||
# include <sanitizer/asan_interface.h>
|
# include <sanitizer/asan_interface.h>
|
||||||
/* How to do manual poisoning:
|
/* How to do manual poisoning:
|
||||||
@ -62,6 +68,7 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
|||||||
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
|
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
|
||||||
# define MEM_GET_VBITS(a,b,len) ((void) 0)
|
# define MEM_GET_VBITS(a,b,len) ((void) 0)
|
||||||
# define MEM_SET_VBITS(a,b,len) ((void) 0)
|
# define MEM_SET_VBITS(a,b,len) ((void) 0)
|
||||||
|
# define MSAN_STAT_WORKAROUND(st) ((void) 0)
|
||||||
# define REDZONE_SIZE 8
|
# define REDZONE_SIZE 8
|
||||||
#else
|
#else
|
||||||
# define MEM_UNDEFINED(a,len) ((void) 0)
|
# define MEM_UNDEFINED(a,len) ((void) 0)
|
||||||
@ -73,6 +80,7 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
|
|||||||
# define MEM_GET_VBITS(a,b,len) ((void) 0)
|
# define MEM_GET_VBITS(a,b,len) ((void) 0)
|
||||||
# define MEM_SET_VBITS(a,b,len) ((void) 0)
|
# define MEM_SET_VBITS(a,b,len) ((void) 0)
|
||||||
# define REDZONE_SIZE 0
|
# define REDZONE_SIZE 0
|
||||||
|
# define MSAN_STAT_WORKAROUND(st) ((void) 0)
|
||||||
#endif /* __has_feature(memory_sanitizer) */
|
#endif /* __has_feature(memory_sanitizer) */
|
||||||
|
|
||||||
#ifdef HAVE_valgrind
|
#ifdef HAVE_valgrind
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
Copyright (c) 2008, 2020, MariaDB Corporation.
|
Copyright (c) 2008, 2022, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -350,11 +350,14 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
|
|||||||
my_flags)))
|
my_flags)))
|
||||||
goto error;
|
goto error;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (! stat((char *) path, (struct stat *) stat_area) )
|
if (!stat((char *) path, (struct stat *) stat_area))
|
||||||
DBUG_RETURN(stat_area);
|
{
|
||||||
|
MSAN_STAT_WORKAROUND(stat_area);
|
||||||
|
DBUG_RETURN(stat_area);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (! my_win_stat(path, stat_area) )
|
if (!my_win_stat(path, stat_area))
|
||||||
DBUG_RETURN(stat_area);
|
DBUG_RETURN(stat_area);
|
||||||
#endif
|
#endif
|
||||||
DBUG_PRINT("error",("Got errno: %d from stat", errno));
|
DBUG_PRINT("error",("Got errno: %d from stat", errno));
|
||||||
my_errno= errno;
|
my_errno= errno;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2001, 2011, Oracle and/or its affiliates
|
Copyright (c) 2001, 2011, Oracle and/or its affiliates
|
||||||
Copyright (c) 2010, 2017, MariaDB
|
Copyright (c) 2010, 2022, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -113,7 +113,10 @@ int my_is_symlink(const char *filename __attribute__((unused)))
|
|||||||
{
|
{
|
||||||
#if defined (HAVE_LSTAT) && defined (S_ISLNK)
|
#if defined (HAVE_LSTAT) && defined (S_ISLNK)
|
||||||
struct stat stat_buff;
|
struct stat stat_buff;
|
||||||
return !lstat(filename, &stat_buff) && S_ISLNK(stat_buff.st_mode);
|
if (lstat(filename, &stat_buff))
|
||||||
|
return 0;
|
||||||
|
MSAN_STAT_WORKAROUND(&stat_buff);
|
||||||
|
return !!S_ISLNK(stat_buff.st_mode);
|
||||||
#elif defined (_WIN32)
|
#elif defined (_WIN32)
|
||||||
DWORD dwAttr = GetFileAttributes(filename);
|
DWORD dwAttr = GetFileAttributes(filename);
|
||||||
return (dwAttr != INVALID_FILE_ATTRIBUTES) &&
|
return (dwAttr != INVALID_FILE_ATTRIBUTES) &&
|
||||||
|
@ -128,6 +128,8 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name)
|
|||||||
if (mysql_file_fstat(file, &state, MYF(MY_WME)))
|
if (mysql_file_fstat(file, &state, MYF(MY_WME)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
MSAN_STAT_WORKAROUND(&state);
|
||||||
|
|
||||||
if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME)))
|
if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
Copyright (c) 2009, 2020, MariaDB Corporation.
|
Copyright (c) 2009, 2022, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -72,6 +72,7 @@ int readfrm(const char *name, const uchar **frmdata, size_t *len)
|
|||||||
error= 2;
|
error= 2;
|
||||||
if (mysql_file_fstat(file, &state, MYF(0)))
|
if (mysql_file_fstat(file, &state, MYF(0)))
|
||||||
goto err;
|
goto err;
|
||||||
|
MSAN_STAT_WORKAROUND(&state);
|
||||||
read_len= (size_t)MY_MIN(FRM_MAX_SIZE, state.st_size); // safety
|
read_len= (size_t)MY_MIN(FRM_MAX_SIZE, state.st_size); // safety
|
||||||
|
|
||||||
// Read whole frm file
|
// Read whole frm file
|
||||||
|
@ -415,6 +415,8 @@ sql_parse_prepare(const LEX_CSTRING *file_name, MEM_ROOT *mem_root,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSAN_STAT_WORKAROUND(&stat_info);
|
||||||
|
|
||||||
if (stat_info.st_size > INT_MAX-1)
|
if (stat_info.st_size > INT_MAX-1)
|
||||||
{
|
{
|
||||||
my_error(ER_FPARSER_TOO_BIG_FILE, MYF(0), file_name->str);
|
my_error(ER_FPARSER_TOO_BIG_FILE, MYF(0), file_name->str);
|
||||||
|
@ -953,7 +953,7 @@ os_file_status_posix(
|
|||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* file exists, everything OK */
|
/* file exists, everything OK */
|
||||||
|
MSAN_STAT_WORKAROUND(&statinfo);
|
||||||
} else if (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) {
|
} else if (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) {
|
||||||
/* file does not exist */
|
/* file does not exist */
|
||||||
return(true);
|
return(true);
|
||||||
@ -1548,8 +1548,10 @@ bool os_file_close_func(os_file_t file)
|
|||||||
os_offset_t
|
os_offset_t
|
||||||
os_file_get_size(os_file_t file)
|
os_file_get_size(os_file_t file)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
|
if (fstat(file, &statbuf)) return os_offset_t(-1);
|
||||||
|
MSAN_STAT_WORKAROUND(&statbuf);
|
||||||
|
return statbuf.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a file size.
|
/** Gets a file size.
|
||||||
@ -1566,6 +1568,7 @@ os_file_get_size(
|
|||||||
int ret = stat(filename, &s);
|
int ret = stat(filename, &s);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
MSAN_STAT_WORKAROUND(&s);
|
||||||
file_size.m_total_size = s.st_size;
|
file_size.m_total_size = s.st_size;
|
||||||
/* st_blocks is in 512 byte sized blocks */
|
/* st_blocks is in 512 byte sized blocks */
|
||||||
file_size.m_alloc_size = s.st_blocks * 512;
|
file_size.m_alloc_size = s.st_blocks * 512;
|
||||||
@ -1610,6 +1613,8 @@ os_file_get_status_posix(
|
|||||||
return(DB_FAIL);
|
return(DB_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSAN_STAT_WORKAROUND(statinfo);
|
||||||
|
|
||||||
switch (statinfo->st_mode & S_IFMT) {
|
switch (statinfo->st_mode & S_IFMT) {
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
stat_info->type = OS_FILE_TYPE_DIR;
|
stat_info->type = OS_FILE_TYPE_DIR;
|
||||||
@ -3300,6 +3305,7 @@ fallback:
|
|||||||
if (fstat(file, &statbuf)) {
|
if (fstat(file, &statbuf)) {
|
||||||
err = errno;
|
err = errno;
|
||||||
} else {
|
} else {
|
||||||
|
MSAN_STAT_WORKAROUND(&statbuf);
|
||||||
os_offset_t current_size = statbuf.st_size;
|
os_offset_t current_size = statbuf.st_size;
|
||||||
if (current_size >= size) {
|
if (current_size >= size) {
|
||||||
return true;
|
return true;
|
||||||
@ -4186,6 +4192,7 @@ void fil_node_t::find_metadata(os_file_t file
|
|||||||
#else
|
#else
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
if (!statbuf && !fstat(file, &sbuf)) {
|
if (!statbuf && !fstat(file, &sbuf)) {
|
||||||
|
MSAN_STAT_WORKAROUND(&sbuf);
|
||||||
statbuf = &sbuf;
|
statbuf = &sbuf;
|
||||||
}
|
}
|
||||||
if (statbuf) {
|
if (statbuf) {
|
||||||
@ -4229,6 +4236,7 @@ bool fil_node_t::read_page0()
|
|||||||
if (fstat(handle, &statbuf)) {
|
if (fstat(handle, &statbuf)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
MSAN_STAT_WORKAROUND(&statbuf);
|
||||||
os_offset_t size_bytes = statbuf.st_size;
|
os_offset_t size_bytes = statbuf.st_size;
|
||||||
#else
|
#else
|
||||||
os_offset_t size_bytes = os_file_get_size(handle);
|
os_offset_t size_bytes = os_file_get_size(handle);
|
||||||
|
@ -704,10 +704,11 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
|
|||||||
}
|
}
|
||||||
else if (*fmt == 'f' || *fmt == 'g')
|
else if (*fmt == 'f' || *fmt == 'g')
|
||||||
{
|
{
|
||||||
|
double d;
|
||||||
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
|
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
|
||||||
__msan_check_mem_is_initialized(ap, sizeof(double));
|
__msan_check_mem_is_initialized(ap, sizeof(double));
|
||||||
#endif
|
#endif
|
||||||
double d= va_arg(ap, double);
|
d= va_arg(ap, double);
|
||||||
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
|
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
|
||||||
__msan_unpoison(&d, sizeof(double));
|
__msan_unpoison(&d, sizeof(double));
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user