]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix recently-introduced profile parsing bugs 1348/head
authorGreg Hudson <ghudson@mit.edu>
Tue, 21 May 2024 23:10:50 +0000 (19:10 -0400)
committerGreg Hudson <ghudson@mit.edu>
Tue, 28 May 2024 20:34:49 +0000 (16:34 -0400)
When parsing a "}", do not ascend to the parent node if we are still
within a discarded section after decrementing group_level, as we did
not descend into a child node at the beginning of the subsection.
(Discovered by OSS-Fuzz.)

Also adjust the level check to take into account the shifted meaning
of state->group_level, so that we properly reject a "}" within a
top-level section.

Both bugs were introduced in commit
f951625e6bd3ff44f1056958b56e35a1a043e362.

src/util/profile/final6.ini
src/util/profile/prof_parse.c

index c1e44b747e4c81fd5aec88ef19970229d0dbed86..0035c474e8e012f4bad0aaf6981aa789ddc00ae4 100644 (file)
        bb = {
                bba = 2
        }
+       # Regression test for a bug where each subsection within a
+       # discarded section caused the parser to ascend into the
+       # parent node without descending into a child node first.
+       bb = {
+       }
+       bb = {
+       }
 
 [c]
        ca* = {
index c581fb722247e8265c3fa94e16431086afb859b0..2e329de4e033650b9edcca7874e8587b32fc64bb 100644 (file)
@@ -124,18 +124,22 @@ static errcode_t parse_std_line(char *line, struct parse_state *state)
         return 0;
     }
     if (ch == '}') {
-        if (state->group_level == 0)
+        if (state->group_level < 2)
             return PROF_EXTRA_CBRACE;
         if (*(cp+1) == '*')
             profile_make_node_final(state->current_section);
-        retval = profile_get_node_parent(state->current_section,
-                                         &state->current_section);
-        if (retval)
-            return retval;
         state->group_level--;
         /* Check if we are done discarding values from a subsection. */
         if (state->group_level < state->discard)
             state->discard = 0;
+        /* Ascend to the current node's parent, unless the subsection we ended
+         * was discarded (in which case we never descended). */
+        if (!state->discard) {
+            retval = profile_get_node_parent(state->current_section,
+                                             &state->current_section);
+            if (retval)
+                return retval;
+        }
         return 0;
     }
     /*