From 9c36990eb48d41907357a159a88c4cf5eb018271 Mon Sep 17 00:00:00 2001 From: Ilya Verbin <iverbin@tarantool.org> Date: Thu, 10 Oct 2024 21:36:43 +0300 Subject: [PATCH] box: fix SIGSEGV on unaligned access to a struct with extended alignment All structures with a non-default alignment (set by `alignas()`) must be allocated by `aligned_alloc()`, otherwise an access to such a structure member fill crash, e.g. if compiled with AVX-512 support. Closes #10215 Part of #10631 NO_DOC=bugfix NO_TEST=tested by debug_asan_clang workflow NO_CHANGELOG=fix is actually not user-visible, because tarantool still doesn't work with enabled AVX-512 (#10671) (cherry picked from commit a60ec82d4f07720148b0724e5feff31f76291b56) --- src/box/applier.cc | 2 +- src/box/iproto.cc | 4 ++-- src/box/relay.cc | 12 +----------- src/box/replication.cc | 4 ---- src/trivia/util.h | 8 ++++++++ 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/box/applier.cc b/src/box/applier.cc index d2eba45248..1132081826 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -2130,7 +2130,7 @@ applier_init(void) sizeof(struct applier_thread *)); for (int i = 0; i < replication_threads; i++) { struct applier_thread *thread = - (struct applier_thread *)xmalloc(sizeof(*thread)); + xalloc_object(struct applier_thread); applier_thread_create(thread); applier_threads[i] = thread; } diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 2808303b80..4217151eff 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -3232,8 +3232,8 @@ iproto_init(int threads_count) * we don't need any accept functions. */ evio_service_create(loop(), &tx_binary, "tx_binary", NULL, NULL); - iproto_threads = (struct iproto_thread *) - xcalloc(threads_count, sizeof(struct iproto_thread)); + iproto_threads = xalloc_array(struct iproto_thread, threads_count); + memset(iproto_threads, 0, sizeof(struct iproto_thread) * threads_count); for (int i = 0; i < threads_count; i++, iproto_threads_count++) { struct iproto_thread *iproto_thread = &iproto_threads[i]; diff --git a/src/box/relay.cc b/src/box/relay.cc index 5b1967d391..10edf513a6 100644 --- a/src/box/relay.cc +++ b/src/box/relay.cc @@ -286,14 +286,7 @@ relay_new(struct replica *replica) * (Use clang UB Sanitizer, to make sure of this) */ assert((sizeof(struct relay) % alignof(struct relay)) == 0); - struct relay *relay = (struct relay *) - aligned_alloc(alignof(struct relay), sizeof(struct relay)); - if (relay == NULL) { - diag_set(OutOfMemory, sizeof(struct relay), "aligned_alloc", - "struct relay"); - return NULL; - } - + struct relay *relay = xalloc_object(struct relay); memset(relay, 0, sizeof(struct relay)); relay->replica = replica; relay->last_row_time = ev_monotonic_now(loop()); @@ -451,9 +444,6 @@ relay_initial_join(struct iostream *io, uint64_t sync, struct vclock *vclock, struct checkpoint_cursor *cursor) { struct relay *relay = relay_new(NULL); - if (relay == NULL) - diag_raise(); - relay_start(relay, io, sync, relay_send_initial_join_row, relay_yield, UINT64_MAX); auto relay_guard = make_scoped_guard([=] { diff --git a/src/box/replication.cc b/src/box/replication.cc index b28bf8519d..8d2caaf0ba 100644 --- a/src/box/replication.cc +++ b/src/box/replication.cc @@ -257,10 +257,6 @@ replica_new(void) "struct replica"); } replica->relay = relay_new(replica); - if (replica->relay == NULL) { - free(replica); - diag_raise(); - } replica->id = 0; replica->anon = false; replica->uuid = uuid_nil; diff --git a/src/trivia/util.h b/src/trivia/util.h index 7b515a1570..a2abe3a6d4 100644 --- a/src/trivia/util.h +++ b/src/trivia/util.h @@ -131,6 +131,14 @@ alloc_failure(const char *filename, int line, size_t size) #define xrealloc(ptr, size) xalloc_impl((size), realloc, (ptr), (size)) #define xstrdup(s) xalloc_impl(strlen((s)) + 1, strdup, (s)) #define xstrndup(s, n) xalloc_impl((n) + 1, strndup, (s), (n)) +#define xaligned_alloc(size, align) \ + xalloc_impl((size), aligned_alloc, (align), (size)) +#define xalloc_object(T) ({ \ + (T *)xaligned_alloc(sizeof(T), alignof(T)); \ +}) +#define xalloc_array(T, count) ({ \ + (T *)xaligned_alloc(sizeof(T) * (count), alignof(T)); \ +}) #define xmempool_alloc(p) xalloc_impl((p)->objsize, mempool_alloc, (p)) #define xregion_alloc(p, size) xalloc_impl((size), region_alloc, (p), (size)) #define xregion_aligned_alloc(p, size, align) \ -- GitLab