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: 98d0343870 ("Implemented a HA enabled in-memory address pool")
This commit is contained in:
Tobias Brunner
2026-07-24 08:47:39 +02:00
parent e3607d546d
commit c52fd0c518
+14 -5
View File
@@ -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);