]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
More safe chain sorting, improving r7098
authorJesper Dangaard Brouer <hawk@comx.dk>
Wed, 12 Dec 2007 15:20:42 +0000 (15:20 +0000)
committerPatrick McHardy <kaber@trash.net>
Wed, 12 Dec 2007 15:20:42 +0000 (15:20 +0000)
This patch is an improvment of r7098 (made by me).

Assuring compatibility between 1.4.0 and older versions,
regarding chain sorting.

Chains from kernel are already sorted, as they are inserted
sorted. But there exists an issue when shifting to 1.4.0
from an older version, as old versions allow last created
chain to be unsorted.  This unsorted chain would survive in
1.4.0, as chains are now only sorted on creation.

This patch verifies that chains are sorted, if not it fixes the sorting.

Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
libiptc/libiptc.c

index 059850503c32eb1ba5b20d58da23a2fe27611d96..29f671e6ef3746887fec8625d74bff7c52585afc 100644 (file)
@@ -415,12 +415,28 @@ static inline void iptc_insert_chain(TC_HANDLE_T h, struct chain_head *c)
 static void __iptcc_p_add_chain(TC_HANDLE_T h, struct chain_head *c,
                                unsigned int offset, unsigned int *num)
 {
+       struct list_head  *tail = h->chains.prev;
+       struct chain_head *ctail;
+
        __iptcc_p_del_policy(h, *num);
 
        c->head_offset = offset;
        c->index = *num;
 
-       list_add_tail(&c->list, &h->chains); /* Its already sorted */
+       /* Chains from kernel are already sorted, as they are inserted
+        * sorted. But there exists an issue when shifting to 1.4.0
+        * from an older version, as old versions allow last created
+        * chain to be unsorted.
+        */
+       if (iptcc_is_builtin(c)) /* Only user defined chains are sorted*/
+               list_add_tail(&c->list, &h->chains);
+       else {
+               ctail = list_entry(tail, struct chain_head, list);
+               if (strcmp(c->name, ctail->name) > 0)
+                       list_add_tail(&c->list, &h->chains);/* Already sorted*/
+               else
+                       iptc_insert_chain(h, c);/* Was not sorted */
+       }
 
        h->chain_iterator_cur = c;
 }