summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Wagner <daniel.wagner@bmw-carit.de>2013-03-12 18:16:45 +0100
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-03-18 14:31:26 +0200
commitedaf6f6182a256a29926b0c016d72cc50f1f0c75 (patch)
tree463320985b92ae501243d816cb8c314fdcf12673 /src
parentd179882d6264f0a7ead2819336185e90cb41798e (diff)
downloadconnman-edaf6f6182a256a29926b0c016d72cc50f1f0c75.tar.gz
connman-edaf6f6182a256a29926b0c016d72cc50f1f0c75.tar.bz2
connman-edaf6f6182a256a29926b0c016d72cc50f1f0c75.zip
iptables: Fix invalid access to list after removing first rule
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.
Diffstat (limited to 'src')
-rw-r--r--src/iptables.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/iptables.c b/src/iptables.c
index 5e24efb0..2c6580be 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;