Merge pull request #6925 from yandex/aku/msan

Some MemorySanitizer fixes
This commit is contained in:
akuzm 2019-09-13 20:26:48 +03:00 committed by GitHub
commit e765733a26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 0 deletions

View File

@ -0,0 +1,9 @@
#pragma once
#define __msan_unpoison(X, Y)
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# undef __msan_unpoison
# include <sanitizer/msan_interface.h>
# endif
#endif

View File

@ -254,6 +254,9 @@ void geohashDecode(const char * encoded_string, size_t encoded_len, Float64 * lo
const UInt8 precision = std::min(encoded_len, static_cast<size_t>(MAX_PRECISION));
if (precision == 0)
{
// Empty string is converted to (0, 0)
*longitude = 0;
*latitude = 0;
return;
}

View File

@ -2,6 +2,7 @@
#include <Common/Exception.h>
#include <common/logger_useful.h>
#include <Common/MemorySanitizer.h>
#include <Poco/Logger.h>
#include <boost/range/iterator_range.hpp>
#include <errno.h>
@ -69,6 +70,9 @@ int AIOContextPool::getCompletionEvents(io_event events[], const int max_events)
if (errno != EINTR)
throwFromErrno("io_getevents: Failed to wait for asynchronous IO completion", ErrorCodes::CANNOT_IO_GETEVENTS, errno);
/// Unpoison the memory returned from a non-instrumented system call.
__msan_unpoison(events, sizeof(*events) * num_events);
return num_events;
}

View File

@ -1,6 +1,7 @@
#if defined(__linux__) || defined(__FreeBSD__)
#include <IO/WriteBufferAIO.h>
#include <Common/MemorySanitizer.h>
#include <Common/ProfileEvents.h>
#include <limits>
@ -200,6 +201,9 @@ bool WriteBufferAIO::waitForAIOCompletion()
}
}
// Unpoison the memory returned from an uninstrumented system function.
__msan_unpoison(&event, sizeof(event));
is_pending_write = false;
#if defined(__FreeBSD__)
bytes_written = aio_return(reinterpret_cast<struct aiocb *>(event.udata));

View File

@ -1,4 +1,5 @@
#include <IO/ZlibDeflatingWriteBuffer.h>
#include <Common/MemorySanitizer.h>
namespace DB
@ -70,6 +71,12 @@ void ZlibDeflatingWriteBuffer::nextImpl()
int rc = deflate(&zstr, Z_NO_FLUSH);
out.position() = out.buffer().end() - zstr.avail_out;
// Unpoison the result of deflate explicitly. It uses some custom SSE algo
// for computing CRC32, and it looks like msan is unable to comprehend
// it fully, so it complains about the resulting value depending on the
// uninitialized padding of the input buffer.
__msan_unpoison(out.position(), zstr.avail_out);
if (rc != Z_OK)
throw Exception(std::string("deflate failed: ") + zError(rc), ErrorCodes::ZLIB_DEFLATE_FAILED);
}
@ -92,6 +99,12 @@ void ZlibDeflatingWriteBuffer::finish()
int rc = deflate(&zstr, Z_FINISH);
out.position() = out.buffer().end() - zstr.avail_out;
// Unpoison the result of deflate explicitly. It uses some custom SSE algo
// for computing CRC32, and it looks like msan is unable to comprehend
// it fully, so it complains about the resulting value depending on the
// uninitialized padding of the input buffer.
__msan_unpoison(out.position(), zstr.avail_out);
if (rc == Z_STREAM_END)
{
finished = true;

View File

@ -20,6 +20,13 @@
#define USE_PHDR_CACHE 1
#endif
#define __msan_unpoison(X, Y)
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# undef __msan_unpoison
# include <sanitizer/msan_interface.h>
# endif
#endif
/// Thread Sanitizer uses dl_iterate_phdr function on initialization and fails if we provide our own.
#ifdef USE_PHDR_CACHE
@ -99,6 +106,10 @@ void updatePHDRCache()
PHDRCache * new_phdr_cache = new PHDRCache;
getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * data)
{
// `info` is created by dl_iterate_phdr, which is a non-instrumented
// libc function, so we have to unpoison it manually.
__msan_unpoison(info, sizeof(*info));
reinterpret_cast<PHDRCache *>(data)->push_back(*info);
return 0;
}, new_phdr_cache);