]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix field alignment issue
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 15 Dec 2022 01:03:22 +0000 (19:03 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 15 Dec 2022 01:03:22 +0000 (19:03 -0600)
src/lib/util/pair.c
src/lib/util/pair.h
src/lib/util/value.h

index 6f53a08ea8ffaa2ae9003ef90cdf2db64d0c5804..626341f725ff4e68a2bd5256da6dd26f7a45b0ca 100644 (file)
@@ -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));
index b176be33b0a7ba48c797e02978897579b960eede..fe44edfe25290ce31c94333393edde13751c0dc0 100644 (file)
@@ -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.
                };
        };
 
index b8c10e0d1c3e775f2ff0045b3c71a2fc63d40373..0bfe57ec728785e2a12bc93647e7f55ce223960b 100644 (file)
@@ -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