From 55a29d1a2697e15a7e99f2158c33ab6c90863ec9 Mon Sep 17 00:00:00 2001
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Thu, 14 May 2020 00:19:43 +0200
Subject: [PATCH] uuid: fix unaligned memory access

Functions tt_uuid_is_nil() and tt_uuid_is_equal() used struct
tt_uuid as an array of two uint64. But it is wrong, because struct
tt_uuid has 4 byte alignment, while uint64 requires 8. That led to
unaligned memory access in these 2 functions.

The patch makes these functions use memcmp() - it appers to be
faster (disassembly shows much smaller code and without jumps),
and does not depend on alignment.

Part of #4609

Reviewed-by: Aleksandr Lyapunov <alyapunov@tarantool.org>
Reviewed-by: Timur Safin <tsafin@tarantool.org>
---
 src/lib/uuid/tt_uuid.h | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/src/lib/uuid/tt_uuid.h b/src/lib/uuid/tt_uuid.h
index c2c436ed48..70c3b98b10 100644
--- a/src/lib/uuid/tt_uuid.h
+++ b/src/lib/uuid/tt_uuid.h
@@ -149,19 +149,6 @@ tt_uuid_bswap(struct tt_uuid *uu)
 	uu->time_hi_and_version = bswap_u16(uu->time_hi_and_version);
 }
 
-/**
- * \brief Test that uuid is nil
- * \param uu UUID
- * \retval true if all members of \a uu 0
- * \retval false otherwise
- */
-inline bool
-tt_uuid_is_nil(const struct tt_uuid *uu)
-{
-	const uint64_t *p = (const uint64_t *) uu;
-	return !p[0] && !p[1];
-}
-
 /**
  * \brief Test that \a lhs equal \a rhs
  * \param lhs UUID
@@ -172,13 +159,23 @@ tt_uuid_is_nil(const struct tt_uuid *uu)
 inline bool
 tt_uuid_is_equal(const struct tt_uuid *lhs, const struct tt_uuid *rhs)
 {
-	const uint64_t *lp = (const uint64_t *) lhs;
-	const uint64_t *rp = (const uint64_t *) rhs;
-	return lp[0] == rp[0] && lp[1] == rp[1];
+	return memcmp(lhs, rhs, sizeof(*lhs)) == 0;
 }
 
 extern const struct tt_uuid uuid_nil;
 
+/**
+ * \brief Test that uuid is nil.
+ * \param uu UUID.
+ * \retval true If all members of \a uu 0.
+ * \retval false Otherwise.
+ */
+inline bool
+tt_uuid_is_nil(const struct tt_uuid *uu)
+{
+	return tt_uuid_is_equal(uu, &uuid_nil);
+}
+
 char *
 tt_uuid_str(const struct tt_uuid *uu);
 
-- 
GitLab