aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsharpeye <sharpeye@yandex-team.ru>2022-04-18 18:40:19 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-04-18 18:40:19 +0300
commitdf455b910e1d049369547fe5c4e83417eb7a73a1 (patch)
tree4786c589e5f78888154b0a43b40cd5bd70ba493f
parentf726434f721abdb4097e50dfa280a5396bbaec51 (diff)
downloadydb-df455b910e1d049369547fe5c4e83417eb7a73a1.tar.gz
[merge to stable-22-2] Fix a segfault in debug mode when the allocated memory accidentally contains 0xF0000000
Наш сервис при сборке с `ALLOCATOR(LF_DBG)` на старте падает [в этой строчке](https://a.yandex-team.ru/arc_vcs/commit/r7923656#file-library/cpp/lfalloc/lf_allocX64.h:R1901) при попытке разыменовать очевидно невалидный указатель. В gdb видно, что мы при попытке определить координаты фиктивного заголовка в `GetAllocHeader()` прочитали какие-то левые 32 бита в качестве `header->Tag`, и они по стечению обстоятельств оказались равны `0xF0000000` в нашем случае (просто не повезло). После этого мы решаем, что в `header->Size` лежит настоящий указатель на заголовок, хотя на самом деле там лежит тоже что-то рандомное. Решение, вроде бы, простое — когда формируем фиктивный заголовок, надо не обращать внимания на теги (потому что к этому моменту их ещё некому было записать). REVIEW: 2408267 REVIEW: 2438642 x-ydb-stable-ref: 02ccf11b927a06e81b968e8b45c287957b8e1d60
-rw-r--r--library/cpp/lfalloc/lf_allocX64.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/library/cpp/lfalloc/lf_allocX64.h b/library/cpp/lfalloc/lf_allocX64.h
index fd2a906d6f..c9150b99ba 100644
--- a/library/cpp/lfalloc/lf_allocX64.h
+++ b/library/cpp/lfalloc/lf_allocX64.h
@@ -1320,7 +1320,12 @@ static inline void* GetAllocPtr(TAllocHeader* p) {
}
static inline TAllocHeader* GetAllocHeader(void* p) {
- auto* header = ((TAllocHeader*)p) - 1;
+ return ((TAllocHeader*)p) - 1;
+}
+
+// if present, uses the fake header stored by LFPosixMemalign() to retrieve the original header.
+static inline TAllocHeader* GetOrigAllocHeader(void* p) {
+ auto* header = GetAllocHeader(p);
if (header->Tag == DBG_ALLOC_ALIGNED_TAG) {
return (TAllocHeader*)header->Size;
}
@@ -1585,7 +1590,7 @@ static Y_FORCE_INLINE void LFFree(void* p) {
#if defined(LFALLOC_DBG)
if (p == nullptr)
return;
- p = GetAllocHeader(p);
+ p = GetOrigAllocHeader(p);
#endif
uintptr_t chkOffset = ((char*)p - ALLOC_START) - 1ll;
@@ -1648,7 +1653,7 @@ static size_t LFGetSize(const void* p) {
#if defined(LFALLOC_DBG)
if (p == nullptr)
return 0;
- return GetAllocHeader(const_cast<void*>(p))->Size;
+ return GetOrigAllocHeader(const_cast<void*>(p))->Size;
#endif
uintptr_t chkOffset = ((const char*)p - ALLOC_START);