From b0b4d23b6f3d679aa6136b0058fe73ede36ed1d4 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Fri, 4 Sep 2026 18:17:16 +0300 Subject: [PATCH] fix misaligned placement-new storages in runtime Static char storages used as backing memory for placement new of array had alignment 1, which is UB when the linker places them at an address not aligned to alignof(array). UBSan (clang-18) reports "constructor call on misaligned address" at startup of every runtime unit test. Add alignas() to all such storages. Co-Authored-By: Claude Code --- runtime/files.cpp | 4 ++-- runtime/interface.cpp | 6 +++--- runtime/openssl.cpp | 2 +- runtime/regexp.cpp | 2 +- runtime/udp.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/runtime/files.cpp b/runtime/files.cpp index 781ef78ccf..ea51f2d3aa 100644 --- a/runtime/files.cpp +++ b/runtime/files.cpp @@ -423,7 +423,7 @@ Optional f$realpath(const string& path) { } static Optional full_realpath(const string& path) { // realpath resolving only dirname to work with unexisted files - static char full_realpath_cache_storage[sizeof(array)]; + alignas(array) static char full_realpath_cache_storage[sizeof(array)]; static array* full_realpath_cache = reinterpret_cast*>(full_realpath_cache_storage); static long long full_realpath_last_query_num = -1; @@ -567,7 +567,7 @@ Optional> f$scandir(const string& directory) { return file_list; } -static char opened_files_storage[sizeof(array)]; +alignas(array) static char opened_files_storage[sizeof(array)]; static array* opened_files = reinterpret_cast*>(opened_files_storage); static long long opened_files_last_query_num = -1; diff --git a/runtime/interface.cpp b/runtime/interface.cpp index 7cf80c0400..6f00bb2357 100644 --- a/runtime/interface.cpp +++ b/runtime/interface.cpp @@ -207,7 +207,7 @@ int64_t f$ob_get_level() { static int http_return_code; static string http_status_line; -static char headers_storage[sizeof(array)]; +alignas(array) static char headers_storage[sizeof(array)]; static array* headers = reinterpret_cast*>(headers_storage); static long long header_last_query_num = -1; static bool headers_custom_handler_invoked = false; @@ -1329,7 +1329,7 @@ static bool parse_multipart(const char* post, int post_len, const string& bounda return true; } -static char arg_vars_storage[sizeof(array)]; +alignas(array) static char arg_vars_storage[sizeof(array)]; static array* arg_vars = nullptr; Optional& get_dummy_rest_index() noexcept { @@ -1897,7 +1897,7 @@ std::tuple f$get_webserver_stats() { return {stats.running_workers, stats.waiting_workers, stats.ready_for_accept_workers, stats.total_workers}; } -static char ini_vars_storage[sizeof(array)]; +alignas(array) static char ini_vars_storage[sizeof(array)]; static array* ini_vars = nullptr; void ini_set(vk::string_view key, vk::string_view value) { diff --git a/runtime/openssl.cpp b/runtime/openssl.cpp index 5add08b022..aa34696d84 100644 --- a/runtime/openssl.cpp +++ b/runtime/openssl.cpp @@ -598,7 +598,7 @@ struct ssl_connection { SSL_CTX* ssl_ctx; }; -static char ssl_connections_storage[sizeof(array)]; +alignas(array) static char ssl_connections_storage[sizeof(array)]; static array* ssl_connections = reinterpret_cast*>(ssl_connections_storage); static long long ssl_connections_last_query_num = -1; diff --git a/runtime/regexp.cpp b/runtime/regexp.cpp index dedcf66812..973965b4bb 100644 --- a/runtime/regexp.cpp +++ b/runtime/regexp.cpp @@ -311,7 +311,7 @@ bool regexp::is_valid_RE2_regexp(const char* regexp_string, int64_t regexp_len, } void regexp::init(const string& regexp_string, const char* function, const char* file) { - static char regexp_cache_storage[sizeof(array)]; + alignas(array) static char regexp_cache_storage[sizeof(array)]; static array* regexp_cache = (array*)regexp_cache_storage; static long long regexp_last_query_num = -1; diff --git a/runtime/udp.cpp b/runtime/udp.cpp index 3112e11d5a..010699fc9e 100644 --- a/runtime/udp.cpp +++ b/runtime/udp.cpp @@ -19,7 +19,7 @@ int DEFAULT_SOCKET_TIMEOUT = 60; -static char opened_udp_sockets_storage[sizeof(array)]; +alignas(array) static char opened_udp_sockets_storage[sizeof(array)]; static array* opened_udp_sockets = reinterpret_cast*>(opened_udp_sockets_storage); static long long opened_udp_sockets_last_query_num = -1;