diff options
author | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2013-03-12 18:16:45 +0100 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2013-03-18 14:31:26 +0200 |
commit | edaf6f6182a256a29926b0c016d72cc50f1f0c75 (patch) | |
tree | 463320985b92ae501243d816cb8c314fdcf12673 /src | |
parent | d179882d6264f0a7ead2819336185e90cb41798e (diff) | |
download | connman-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.c | 22 |
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; |