netfilter: ipset: Reset flags on private copy on set resize

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Set resizing takes read lock on the hash table, so we should
not modify any data in the original hash table, as this would
disrupt concurrent readers.

Furthermore set resizing could fail, leaving original set data
in inconsistent state: flags (nomatch currently) would be
cleared on all, but the last, where reallocation fails, set
elements.

Fix this by taking private copy of original set entry for
sets, where it is necessary.

Signed-off-by: Sergey Popovich <popovich_sergei@xxxxxxx>
---
 net/netfilter/ipset/ip_set_hash_gen.h |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index 7122cd8..fcf75be 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -541,8 +541,9 @@ mtype_resize(struct ip_set *set, bool retried)
 	u8 htable_bits = orig->htable_bits;
 #ifdef IP_SET_HASH_WITH_NETS
 	u8 flags;
+	u8 _data[set->dsize];
 #endif
-	struct mtype_elem *data;
+	struct mtype_elem *data, *hdata;
 	struct mtype_elem *d;
 	struct hbucket *n, *m;
 	u32 i, j;
@@ -581,15 +582,15 @@ retry:
 		for (j = 0; j < n->pos; j++) {
 			data = ahash_data(n, j, set->dsize);
 #ifdef IP_SET_HASH_WITH_NETS
+			hdata = memcpy(_data, data, set->dsize);
 			flags = 0;
-			mtype_data_reset_flags(data, &flags);
+			mtype_data_reset_flags(hdata, &flags);
+#else
+			hdata = data;
 #endif
-			m = hbucket(t, HKEY(data, h->initval, htable_bits));
+			m = hbucket(t, HKEY(hdata, h->initval, htable_bits));
 			ret = hbucket_elem_add(m, AHASH_MAX(h), set->dsize);
 			if (ret < 0) {
-#ifdef IP_SET_HASH_WITH_NETS
-				mtype_data_reset_flags(data, &flags);
-#endif
 				read_unlock_bh(&set->lock);
 				mtype_ahash_destroy(set, t, false);
 				if (ret == -EAGAIN)
@@ -598,9 +599,6 @@ retry:
 			}
 			d = ahash_data(m, m->pos++, set->dsize);
 			memcpy(d, data, set->dsize);
-#ifdef IP_SET_HASH_WITH_NETS
-			mtype_data_reset_flags(d, &flags);
-#endif
 		}
 	}
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux