]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
reset the input pointer if it changes. Fixex #5462
authorAlan T. DeKok <aland@freeradius.org>
Wed, 27 Nov 2024 16:30:29 +0000 (11:30 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 27 Nov 2024 16:36:51 +0000 (11:36 -0500)
There are larger underlying problems, though.  The API to
fr_sbuff_terminal_search() is wrong.  It accepts an input pointer
"p", which points to somewhere in the middle of the sbuff.

As a result, if the sbuff is shifted due to reads, the sbuff->p
pointer changes, and the "cached" p passed to fr_sbuff_terminal_search()
points to somewhere wild.

As a result, most _callers_ of fr_sbuff_terminal_search() are
likely wrong, too, as they cache p = sbuff->p, and don't expect
that pointer to change under them.

src/lib/util/sbuff.c

index 06678c89fec0cf50a843349ee30141d12024bc23..692884adfd1fc705c9945d214d8dd0521e204231 100644 (file)
@@ -536,11 +536,13 @@ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p,
        ssize_t         mid;
 
        size_t          remaining;
+       bool            reset_p = (p == in->p);
        fr_sbuff_extend_status_t        status = FR_SBUFF_EXTENDABLE;
 
        if (!term) return false;                        /* If there's no terminals, we don't need to search */
 
        end = term->len - 1;
+
        term_idx = idx[(uint8_t)*p];                    /* Fast path */
        if (!term_idx) return false;
 
@@ -553,6 +555,8 @@ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p,
                return (idx['\0'] != 0);
        }
 
+       if (reset_p) p = in->p;
+
        mid = term_idx - 1;                             /* Inform the mid point from the index */
 
        while (start <= end) {