pairadd: Don't add a VP if it's already present
authorJulius Plenz <plenz@cis.fu-berlin.de>
Thu, 9 Oct 2014 10:48:37 +0000 (12:48 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 9 Oct 2014 14:16:46 +0000 (10:16 -0400)
In the 3.0 code base, pairmake() will already do a pairadd()
automatically. If an old code base (e.g. modules originally written for
FreeRADIUS 2.x) uses pairmake() and then pairadd() explicitly, this will
add the VP *twice*, thus creating a cyclic list structure, e.g.:

    A->next == B;
    B->next == B;
    B->next == B;
    B->next == B;
    ...

This makes any function that walks all value pairs end up eating 100%
CPU.

Since VPs are added at the end of the list, we can simply stop
traversing the list and return silently in case the VP is already
present.

Signed-off-by: Julius Plenz <plenz@cis.fu-berlin.de>
src/lib/valuepair.c

index e3be76c..2321fe5 100644 (file)
@@ -283,8 +283,11 @@ void pairadd(VALUE_PAIR **first, VALUE_PAIR *add)
                *first = add;
                return;
        }
-       for(i = *first; i->next; i = i->next)
+       for(i = *first; i->next; i = i->next) {
                VERIFY_VP(i);
+               if(i == add)
+                       return;
+       }
        i->next = add;
 }