From: Arran Cudbard-Bell Date: Thu, 15 Dec 2022 01:03:22 +0000 (-0600) Subject: Fix field alignment issue X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8aa2f5fd7b08c600339e36451b30489961ffa9bb;p=thirdparty%2Ffreeradius-server.git Fix field alignment issue --- diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 6f53a08ea8f..626341f725f 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -183,7 +183,10 @@ static inline CC_HINT(always_inline) void pair_init_from_da(fr_pair_t *vp, fr_di if (likely(fr_type_is_leaf(da->type))) { fr_value_box_init(&vp->data, da->type, da, false); } else { - vp->type = da->type; /* overlaps with vp->vp_type, and everyone needs it! */ + /* + * Hack around const issues... + */ + memcpy(UNCONST(fr_type_t *, &vp->vp_type), &da->type, sizeof(vp->vp_type)); fr_pair_list_init(&vp->vp_group); vp->vp_group.is_child = true; fr_pair_order_list_talloc_init_children(vp, &vp->vp_group.order); @@ -2847,12 +2850,14 @@ void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_p file, line, vp->da->name); } - if (vp->vp_ptr) switch (vp->vp_type) { + switch (vp->vp_type) { case FR_TYPE_OCTETS: { size_t len; TALLOC_CTX *parent; + if (!vp->vp_octets) break; /* We might be in the middle of initialisation */ + if (!talloc_get_type(vp->vp_ptr, uint8_t)) { fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t \"%s\" data buffer type should be " "uint8_t but is %s", file, line, vp->da->name, talloc_get_name(vp->vp_ptr)); @@ -2879,6 +2884,8 @@ void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_p size_t len; TALLOC_CTX *parent; + if (!vp->vp_octets) break; /* We might be in the middle of initialisation */ + if (!talloc_get_type(vp->vp_ptr, char)) { fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t \"%s\" data buffer type should be " "char but is %s", file, line, vp->da->name, talloc_get_name(vp->vp_ptr)); diff --git a/src/lib/util/pair.h b/src/lib/util/pair.h index b176be33b0a..fe44edfe252 100644 --- a/src/lib/util/pair.h +++ b/src/lib/util/pair.h @@ -80,8 +80,17 @@ struct value_pair_s { fr_value_box_t data; //!< The value of this pair. struct { - fr_type_t _CONST type; //!< Type of this value-box, see value.h - fr_pair_list_t children; //!< Nested attributes of this pair. + /** Force children field to come _after_ the type field in the fr_value_box_t + * + * This works no matter where type appears in fr_value_box_t, whereas just + * listing another fr_type_t field here does not. + * + * This hack allows the majority of the fr_pair_list_t to overlap with the + * fr_value_box_t which gives us much greater packing efficiency. + */ + uint8_t pad[offsetof(fr_value_box_t, type) + sizeof(fr_type_t)]; + + fr_pair_list_t children; //!< Nested attributes of this pair. }; }; diff --git a/src/lib/util/value.h b/src/lib/util/value.h index b8c10e0d1c3..0bfe57ec728 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -150,18 +150,18 @@ typedef union { * Don't change the order of the fields below without checing that the output of radsize doesn't change. */ struct value_box_s { - FR_DLIST_ENTRY(fr_value_box_list) entry; //!< Doubly linked list entry. Should be first for efficiently - ///< traversing linked items. - - fr_value_box_datum_t datum; //!< The value held by the value box. - /** Type and flags should appear together for packing efficiency */ fr_type_t _CONST type; //!< Type of this value-box, at the start, see pair.h bool tainted; //!< i.e. did it come from an untrusted source uint16_t _CONST safe; //!< more detailed safety + FR_DLIST_ENTRY(fr_value_box_list) entry; //!< Doubly linked list entry. + fr_dict_attr_t const *enumv; //!< Enumeration values. + + fr_value_box_datum_t datum; //!< The value held by the value box. Should appear + ///< last for packing efficiency. }; /** @name List and cursor function definitions