From: Daniel Wagner <daniel.wag...@bmw-carit.de>

The list pointer is invalid after remove_table_entry(). Since
we entering the 'if' body only for the first rule in a builtin
chain we can safely update list to point to the next element.
---
 src/iptables.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/iptables.c b/src/iptables.c
index 5e24efb..2c6580b 100644
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -1022,6 +1022,22 @@ static int iptables_delete_rule(struct connman_iptables 
*table,
        entry = chain_head->data;
        builtin = entry->builtin;
 
+       if (builtin >= 0 && list == chain_head) {
+               /*
+                * We are about to remove the first rule in the
+                * chain. In this case we need to store the builtin
+                * value to the new chain_head.
+                *
+                * Note, for builtin chains, chain_head->next is
+                * always valid. A builtin chain has always a policy
+                * rule at the end.
+                */
+               chain_head = chain_head->next;
+
+               entry = chain_head->data;
+               entry->builtin = builtin;
+       }
+
        entry = list->data;
        if (entry == NULL)
                return -EINVAL;
@@ -1035,12 +1051,6 @@ static int iptables_delete_rule(struct connman_iptables 
*table,
        removed += remove_table_entry(table, entry);
 
        if (builtin >= 0) {
-               list = list->next;
-               if (list) {
-                       entry = list->data;
-                       entry->builtin = builtin;
-               }
-
                table->underflow[builtin] -= removed;
                for (list = chain_tail; list; list = list->next) {
                        entry = list->data;
-- 
1.8.2.rc3.16.gce432ca

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to