]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add parent DA to fr_pair_verify()
authorAlan T. DeKok <aland@freeradius.org>
Fri, 28 Nov 2025 16:48:25 +0000 (11:48 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 28 Nov 2025 16:48:25 +0000 (11:48 -0500)
and some associated helper functions.  This allows us to do
better checks of parentage.

src/lib/util/pair.c
src/lib/util/pair.h

index 7d9f85bdc6fc234ae41b5f77979ac848e85624d9..80b20644dd9952e93c350cfeb0fa9e769df436f2 100644 (file)
@@ -3080,7 +3080,7 @@ int fr_pair_value_enum_box(fr_value_box_t const **out, fr_pair_t *vp)
 /*
  *     Verify a fr_pair_t
  */
-void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_pair_t const *vp)
+void fr_pair_verify(char const *file, int line, fr_dict_attr_t const *parent_da, fr_pair_list_t const *list, fr_pair_t const *vp)
 {
        (void) talloc_get_type_abort_const(vp, fr_pair_t);
 
@@ -3089,6 +3089,26 @@ void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_p
        }
 
        fr_dict_attr_verify(file, line, vp->da);
+
+
+       /*
+        *      Enforce correct parentage.  If the parent exists, AND it's not a group (because groups break
+        *      the strict hierarchy), then check parentage.
+        *
+        *      We also ignore parentage if either the expected parent or the vp is raw / unknown.  We may
+        *      want to tighten that a little bit, as there are cases where we create raw / unknown
+        *      attributes, and the parent is also raw / unknown.  In which case the parent_da _should_ be the
+        *      same as vp->da->parent.
+        */
+       if (parent_da && (parent_da->type != FR_TYPE_GROUP) &&
+           !parent_da->flags.is_raw && !parent_da->flags.is_unknown &&
+           !vp->da->flags.is_raw && !vp->da->flags.is_unknown) {
+               fr_fatal_assert_msg(vp->da->parent == parent_da,
+                                   "CONSISTENCY CHECK FAILED %s[%d]:  pair %s does not have the correct parentage - "
+                                   "expected parent %s, found different parent %s",
+                                   file, line, vp->da->name, vp->da->parent->name, parent_da->name);
+       }
+
        if (list) {
                fr_fatal_assert_msg(fr_pair_order_list_parent(vp) == &list->order,
                                    "CONSISTENCY CHECK FAILED %s[%d]:  pair does not have the correct parentage "
@@ -3253,7 +3273,7 @@ void fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_p
                                            file, line,
                                            child->da->name, child->da->parent->name, vp->da->name);
 
-                       fr_pair_verify(file, line, &vp->vp_group, child);
+                       fr_pair_verify(file, line, vp->da, &vp->vp_group, child);
                }
 
               UNCONST(fr_pair_t *, vp)->vp_group.verified = true;
index f9874804844266ccf9beb844f2b5c3f8c15171d8..94a6e695566967e733f016157f14f0bd562fc514 100644 (file)
@@ -153,14 +153,16 @@ struct value_pair_s {
  *
  */
 #ifdef WITH_VERIFY_PTR
-void           fr_pair_verify(char const *file, int line, fr_pair_list_t const *list, fr_pair_t const *vp) CC_HINT(nonnull(4));
+void           fr_pair_verify(char const *file, int line, fr_dict_attr_t const *parent, fr_pair_list_t const *list, fr_pair_t const *vp) CC_HINT(nonnull(5));
 
 void           fr_pair_list_verify(char const *file, int line,
                                    TALLOC_CTX const *expected, fr_pair_list_t const *list) CC_HINT(nonnull(4));
 
-#  define PAIR_VERIFY(_x)              fr_pair_verify(__FILE__, __LINE__, NULL, _x)
-#  define PAIR_VERIFY_WITH_LIST(_l, _x)                fr_pair_verify(__FILE__, __LINE__, _l, _x)
+#  define PAIR_VERIFY(_x)              fr_pair_verify(__FILE__, __LINE__, NULL, NULL, _x)
+#  define PAIR_VERIFY_WITH_LIST(_l, _x)                fr_pair_verify(__FILE__, __LINE__, NULL, _l, _x)
 #  define PAIR_LIST_VERIFY(_x) fr_pair_list_verify(__FILE__, __LINE__, NULL, _x)
+#  define PAIR_VERIFY_WITH_PARENT_VP(_p, _x)  fr_pair_verify(__FILE__, __LINE__, (_p)->da, &(_p)->vp_group, _x)
+#  define PAIR_VERIFY_WITH_PARENT_DA(_p, _x)  fr_pair_verify(__FILE__, __LINE__, _p, NULL, _x)
 #else
 DIAG_OFF(nonnull-compare)
 /** Wrapper function to defeat nonnull checks
@@ -194,6 +196,9 @@ DIAG_ON(nonnull-compare)
 #  define PAIR_VERIFY_WITH_LIST(_l, _x)        fr_pair_list_nonnull_assert(_l); \
                                        fr_pair_nonnull_assert(_x)
 #  define PAIR_LIST_VERIFY(_x) fr_pair_list_nonnull_assert(_x)
+#  define PAIR_VERIFY_WITH_PARENT_VP(_p, _x) fr_pair_list_nonnull_assert(_p); \
+                                         fr_pair_list_nonnull_assert(_x)
+#  define PAIR_VERIFY_WITH_PARENT_DA(_p, _x) fr_pair_list_nonnull_assert(_x)
 #endif