Commit c52fd0c518 for strongswan.org
commit c52fd0c518ffa7e7d29da767103c7150bb40e7a2
Author: Tobias Brunner <tobias@strongswan.org>
Date: Mon Jul 13 16:10:39 2026 +0200
ha: Fix offset checks in HA address pool
This applies some of the same fixes found in the previous commit but also
ensures that the offsets are valid before accessing the bitmask. Because
of an off-by-one error in the latter, the last address could get released
incorrectly (the pool constructor explicitly excludes it).
Fixes: 98d03438706f ("Implemented a HA enabled in-memory address pool")
diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c
index 103d1a9378..ebe5ad4a36 100644
--- a/src/libcharon/plugins/ha/ha_attribute.c
+++ b/src/libcharon/plugins/ha/ha_attribute.c
@@ -86,7 +86,7 @@ static host_t* offset2host(pool_t *pool, int offset)
host_t *host;
uint32_t *pos;
- if (offset > pool->size)
+ if (offset >= pool->size)
{
return NULL;
}
@@ -132,13 +132,21 @@ static int host2offset(pool_t *pool, host_t *addr)
}
hosti = ntohl(*(uint32_t*)(host.ptr));
basei = ntohl(*(uint32_t*)(base.ptr));
- if (hosti > basei + pool->size)
+ if (hosti - basei >= pool->size)
{
return -1;
}
return hosti - basei;
}
+/**
+ * Check if the given offset is valid for the size of the pool
+ */
+static bool valid_offset(pool_t *pool, int offset)
+{
+ return offset > 0 && offset < pool->size - 1;
+}
+
/**
* Find a pool by its name
*/
@@ -201,7 +209,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
for (bit = 0; bit < 8; bit++)
{
tmp_offset = byte * 8 + bit;
- if (!(pool->mask[byte] & 1 << bit) &&
+ if (valid_offset(pool, tmp_offset) &&
+ !(pool->mask[byte] & 1 << bit) &&
responsible_for(this, tmp_offset))
{
offset = tmp_offset;
@@ -261,7 +270,7 @@ METHOD(attribute_provider_t, release_address, bool,
continue;
}
offset = host2offset(pool, address);
- if (offset > 0 && offset < pool->size)
+ if (valid_offset(pool, offset))
{
pool->mask[offset / 8] &= ~(1 << (offset % 8));
DBG1(DBG_CFG, "released address %H to HA pool '%s'", address, name);
@@ -286,7 +295,7 @@ METHOD(ha_attribute_t, reserve, void,
if (pool)
{
offset = host2offset(pool, address);
- if (offset > 0 && offset < pool->size)
+ if (valid_offset(pool, offset))
{
pool->mask[offset / 8] |= 1 << (offset % 8);
DBG1(DBG_CFG, "reserved address %H in HA pool '%s'", address, name);