]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
More dictionary attribute validation
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 29 Jun 2021 03:05:33 +0000 (22:05 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 29 Jun 2021 03:05:33 +0000 (22:05 -0500)
src/lib/util/dict.h
src/lib/util/dict_util.c
src/lib/util/pair.c

index b364690d7789195a9293a2806f670bd634f624dd..905a88762d280ecafadb5584108757794e4293aa 100644 (file)
@@ -61,7 +61,7 @@ typedef struct fr_dict fr_dict_t;
 #endif
 
 #ifdef WITH_VERIFY_PTR
-#  define DA_VERIFY(_x)                fr_dict_verify(__FILE__, __LINE__, _x)
+#  define DA_VERIFY(_x)                fr_dict_attr_verify(__FILE__, __LINE__, _x)
 #else
 #  define DA_VERIFY(_x)                fr_cond_assert(_x)
 #endif
@@ -637,14 +637,13 @@ ssize_t                   fr_dict_valid_name(char const *name, ssize_t len);
 
 ssize_t                        fr_dict_valid_oid_str(char const *name, ssize_t len);
 
-void                   fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da);
-
 fr_dict_attr_t const   *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev);
 
 typedef int            (*fr_dict_walk_t)(fr_dict_attr_t const *da, void *uctx);
 
 int                    fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx);
 
+void                   fr_dict_attr_verify(char const *file, int line, fr_dict_attr_t const *da);
 /** @} */
 
 #undef _CONST
index 0d543b3adc161f0940c7a3b19cad7fb203ae9676..e88028cfaec54ecdb32a7673c48e3aa784a801a7 100644 (file)
@@ -2621,6 +2621,8 @@ fr_dict_attr_t *dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const
        fr_hash_table_t         *namespace;
        fr_dict_attr_t          *da;
 
+       DA_VERIFY(parent);
+
        namespace = dict_attr_namespace(parent);
        if (!namespace) {
                fr_strerror_printf("Attribute '%s' does not contain a namespace", parent->name);
@@ -2654,6 +2656,8 @@ fr_dict_attr_t const *fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr
 {
        fr_dict_attr_t const *da;
 
+       DA_VERIFY(parent);
+
        da = dict_attr_by_name(err, parent, name);
        if (!da) return NULL;
 
@@ -3230,6 +3234,8 @@ int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
                        return -1;
                }
 
+               DA_VERIFY(da);
+
                if (p->out) *(p->out) = da;
        }
 
@@ -3676,65 +3682,6 @@ ssize_t fr_dict_valid_oid_str(char const *name, ssize_t len)
        return len;
 }
 
-void fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da)
-{
-       int i;
-       fr_dict_attr_t const *da_p;
-
-       if (!da) fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t pointer was NULL", file, line);
-
-       (void) talloc_get_type_abort_const(da, fr_dict_attr_t);
-
-       if ((!da->flags.is_root) && (da->depth == 0)) {
-               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
-                                    "Is not root, but depth is 0",
-                                    file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr);
-       }
-
-       if (da->depth > FR_DICT_MAX_TLV_STACK) {
-               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
-                                    "Indicated depth (%u) greater than TLV stack depth (%u)",
-                                    file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr,
-                                    da->depth, FR_DICT_MAX_TLV_STACK);
-       }
-
-       for (da_p = da; da_p; da_p = da_p->next) {
-               (void) talloc_get_type_abort_const(da_p, fr_dict_attr_t);
-       }
-
-       for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
-               if (i != (int)da_p->depth) {
-                       fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
-                                            "Depth out of sequence, expected %i, got %u",
-                                            file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr, i, da_p->depth);
-               }
-
-       }
-
-       if ((i + 1) < 0) {
-               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t top of hierarchy was not at depth 0",
-                                    file, line);
-       }
-
-       if (da->parent && (da->parent->type == FR_TYPE_VENDOR) && !fr_dict_attr_has_ext(da, FR_DICT_ATTR_EXT_VENDOR)) {
-               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: VSA missing 'vendor' extension", file, line);
-       }
-
-       switch (da->type) {
-       case FR_TYPE_STRUCTURAL:
-               if (da->type != FR_TYPE_GROUP) {
-                       fr_assert_msg(fr_dict_attr_has_ext(da, FR_DICT_ATTR_EXT_CHILDREN),
-                                     "CONSISTENCY CHECK FAILED %s[%u]: %s missing 'children' extension",
-                                     file, line,
-                                     fr_table_str_by_value(fr_value_box_type_table, da->type, "<INVALID>"));
-               }
-               break;
-
-       default:
-               break;
-       }
-}
-
 /** Iterate over children of a DA.
  *
  *  @param[in] parent  the parent da to iterate over
@@ -3828,3 +3775,75 @@ int fr_dict_walk(fr_dict_attr_t const *da, fr_dict_walk_t callback, void *uctx)
 {
        return dict_walk(da, callback, uctx);
 }
+
+
+void fr_dict_attr_verify(char const *file, int line, fr_dict_attr_t const *da)
+{
+       int i;
+       fr_dict_attr_t const *da_p;
+
+       if (!da) fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t pointer was NULL", file, line);
+
+       (void) talloc_get_type_abort_const(da, fr_dict_attr_t);
+
+       if ((!da->flags.is_root) && (da->depth == 0)) {
+               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
+                                    "Is not root, but depth is 0",
+                                    file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr);
+       }
+
+       if (da->depth > FR_DICT_MAX_TLV_STACK) {
+               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
+                                    "Indicated depth (%u) greater than TLV stack depth (%u)",
+                                    file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr,
+                                    da->depth, FR_DICT_MAX_TLV_STACK);
+       }
+
+       for (da_p = da; da_p; da_p = da_p->next) {
+               (void) talloc_get_type_abort_const(da_p, fr_dict_attr_t);
+       }
+
+       for (i = da->depth, da_p = da; (i >= 0) && da; i--, da_p = da_p->parent) {
+               if (i != (int)da_p->depth) {
+                       fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: "
+                                            "Depth out of sequence, expected %i, got %u",
+                                            file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr, i, da_p->depth);
+               }
+
+       }
+
+       if ((i + 1) < 0) {
+               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t top of hierarchy was not at depth 0",
+                                    file, line);
+       }
+
+       if (da->parent && (da->parent->type == FR_TYPE_VENDOR) && !fr_dict_attr_has_ext(da, FR_DICT_ATTR_EXT_VENDOR)) {
+               fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: VSA missing 'vendor' extension", file, line);
+       }
+
+       switch (da->type) {
+       case FR_TYPE_STRUCTURAL:
+       {
+               if (da->type == FR_TYPE_GROUP) break;
+
+               fr_assert_msg(fr_dict_attr_has_ext(da, FR_DICT_ATTR_EXT_CHILDREN),
+                             "CONSISTENCY CHECK FAILED %s[%u]: %s missing 'children' extension",
+                             file, line,
+                             fr_table_str_by_value(fr_value_box_type_table, da->type, "<INVALID>"));
+
+               fr_assert_msg(fr_dict_attr_has_ext(da, FR_DICT_ATTR_EXT_NAMESPACE),
+                             "CONSISTENCY CHECK FAILED %s[%u]: %s missing 'namespace' extension",
+                             file, line,
+                             fr_table_str_by_value(fr_value_box_type_table, da->type, "<INVALID>"));
+
+               /*
+                *      Check the namespace hash table is ok
+                */
+               (void)talloc_get_type_abort(dict_attr_namespace(da), fr_hash_table_t);
+       }
+               break;
+
+       default:
+               break;
+       }
+}
index 54f54851dbc2c260d4ed0e71faa00fde1cc9454c..0b492af12763f920e604bf7bf42c20aad4fae895 100644 (file)
@@ -2243,8 +2243,8 @@ void fr_pair_verify(char const *file, int line, fr_pair_t const *vp)
                fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t da pointer was NULL", file, line);
        }
 
-       fr_dict_verify(file, line, vp->da);
-       if (vp->data.enumv) fr_dict_verify(file, line, vp->data.enumv);
+       fr_dict_attr_verify(file, line, vp->da);
+       if (vp->data.enumv) fr_dict_attr_verify(file, line, vp->data.enumv);
 
        if (vp->vp_ptr) switch (vp->vp_type) {
        case FR_TYPE_OCTETS: