From 959523f29d52c82f424acd81f018f552e5da139e Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 10 May 2022 11:33:12 +0100 Subject: [PATCH 1/2] Allow check_client messages to have parameters Make the check_client macro use the new "pretty" format. --- src/snmalloc/ds_core/defines.h | 49 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/snmalloc/ds_core/defines.h b/src/snmalloc/ds_core/defines.h index 869310d6e..98fbf39aa 100644 --- a/src/snmalloc/ds_core/defines.h +++ b/src/snmalloc/ds_core/defines.h @@ -166,29 +166,46 @@ namespace snmalloc namespace snmalloc { + /** + * Forward declaration so that this can be called before the pal header is + * included. + */ + template + [[noreturn]] inline void report_fatal_error(Args... args); + + /** + * Forward declaration so that this can be called before the pal header is + * included. + */ + template + inline void message(Args... args); + template SNMALLOC_FAST_PATH_INLINE void UNUSED(Args&&...) {} - inline SNMALLOC_FAST_PATH void check_client_error(const char* const str) + template + inline SNMALLOC_FAST_PATH void + check_client_error(const char* const str, Args... args) { //[[clang::musttail]] - return snmalloc::error(str); + return snmalloc::report_fatal_error(str, args...); } + template inline SNMALLOC_FAST_PATH void - check_client_impl(bool test, const char* const str) + check_client_impl(bool test, const char* const str, Args... args) { if (SNMALLOC_UNLIKELY(!test)) { - if constexpr (DEBUG) + if constexpr (!DEBUG) { - UNUSED(str); + UNUSED(str, args...); SNMALLOC_FAST_FAIL(); } else { - check_client_error(str); + check_client_error(str, args...); } } } @@ -198,25 +215,11 @@ namespace snmalloc #else static constexpr bool CHECK_CLIENT = false; #endif - - /** - * Forward declaration so that this can be called before the pal header is - * included. - */ - template - [[noreturn]] inline void report_fatal_error(Args... args); - - /** - * Forward declaration so that this can be called before the pal header is - * included. - */ - template - inline void message(Args... args); } // namespace snmalloc #ifdef SNMALLOC_CHECK_CLIENT -# define snmalloc_check_client(test, str) \ - snmalloc::check_client_impl(test, str) +# define snmalloc_check_client(test, str, ...) \ + snmalloc::check_client_impl(test, str, ##__VA_ARGS__) #else -# define snmalloc_check_client(test, str) +# define snmalloc_check_client(test, str, ...) #endif From aa4d9ad58dbdf803adad477aba61490af006a87b Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 10 May 2022 10:45:59 +0100 Subject: [PATCH 2/2] Check size is correct if specified Some secure allocators check that the C++ supplied size is correct relative to the meta-data. This adds a check to the secure version of snmalloc to do that. --- src/snmalloc/mem/localalloc.h | 20 ++++++++++++++++++-- src/snmalloc/mem/sizeclasstable.h | 5 +++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/snmalloc/mem/localalloc.h b/src/snmalloc/mem/localalloc.h index 086fd8a01..cd1b6e5fa 100644 --- a/src/snmalloc/mem/localalloc.h +++ b/src/snmalloc/mem/localalloc.h @@ -675,16 +675,32 @@ namespace snmalloc #endif } + void check_size(void* p, size_t size) + { +#ifdef SNMALLOC_CHECK_CLIENT + size = size == 0 ? 1 : size; + auto sc = size_to_sizeclass_full(size); + auto pm_sc = + Backend::Pagemap::get_metaentry(address_cast(p)).get_sizeclass(); + auto rsize = sizeclass_full_to_size(sc); + auto pm_size = sizeclass_full_to_size(pm_sc); + snmalloc_check_client( + sc == pm_sc, "Dealloc rounded size mismatch: {} != {}", rsize, pm_size); +#else + UNUSED(p, size); +#endif + } + SNMALLOC_FAST_PATH void dealloc(void* p, size_t s) { - UNUSED(s); + check_size(p, s); dealloc(p); } template SNMALLOC_FAST_PATH void dealloc(void* p) { - UNUSED(size); + check_size(p, size); dealloc(p); } diff --git a/src/snmalloc/mem/sizeclasstable.h b/src/snmalloc/mem/sizeclasstable.h index b257d0775..fa85d944f 100644 --- a/src/snmalloc/mem/sizeclasstable.h +++ b/src/snmalloc/mem/sizeclasstable.h @@ -120,6 +120,11 @@ namespace snmalloc { return value == 0; } + + constexpr bool operator==(sizeclass_t other) + { + return value == other.value; + } }; using sizeclass_compress_t = uint8_t;