From eae62a07e075acdd8555420f3f961a82eff0a342 Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Mon, 23 Oct 2023 16:28:02 -0500 Subject: [PATCH] ringct: make `rctSigBase` serialization follow strict aliasing rule Accessing an object of type `char` thru an lvalue of type `crypto::hash8` is undefined behavior. https://developers.redhat.com/blog/2020/06/03/the-joys-and-perils-of-aliasing-in-c-and-c-part-2 --- src/ringct/rctTypes.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index ab1a26b26..32cd8dc6f 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -362,11 +362,17 @@ namespace rct { { if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus) { + // Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the + // first 8 bytes of ecdhInfo[i].amount ar.begin_object(); - if (!typename Archive::is_saving()) + crypto::hash8 trunc_amount; // placeholder variable needed to maintain "strict aliasing" + if (!typename Archive::is_saving()) // loading memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes)); - crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount; - FIELD(amount); + else // saving + memcpy(trunc_amount.data, ecdhInfo[i].amount.bytes, sizeof(trunc_amount)); + FIELD(trunc_amount); + if (!typename Archive::is_saving()) // loading + memcpy(ecdhInfo[i].amount.bytes, trunc_amount.data, sizeof(trunc_amount)); ar.end_object(); } else