mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-14 04:28:41 +04:00
realtek: l3: refuse a route id the table cannot hold
find_first_zero_bit() returns the size it was given when every bit is set, and neither route allocator tests for that. On a full table the id becomes MAX_ROUTES or MAX_HOST_ROUTES and set_bit() writes one word past the bitmap: the two bitmaps sit next to each other in struct otto_l3_ctrl, followed by the interface array, so overflowing the prefix one marks host route slot 0 as used and overflowing the host one sets a bit in the first interface pointer. A prefix route id is also the row the route is written at, so it goes on to ask for row 512 of a 512-row table; otto_table_index_ok() refuses the access and warns once per boot, while otto_l3_fib_add_v4() reports success and marks the route offloaded. Say the table is full and return NULL, which the caller already handles: it turns a failed allocation into -ENOSPC. No-op on RTL838x and RTL931x, whose notifiers return early because cfg->setup is NULL. Compile-tested only: reaching either branch takes 512 prefix or 1536 host routes offloaded at once, which the bench cannot produce. Assisted-by: Claude:claude-opus-5 Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net> Link: https://github.com/openwrt/openwrt/pull/25194 Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
1 parent
7f4f824691
commit
2337fa244e
1 file changed
+12
@@ -1013,6 +1013,12 @@ static struct otto_l3_route *otto_l3_host_route_alloc(struct otto_l3_ctrl *ctrl,
|
||||
mutex_lock(ctrl->lock);
|
||||
|
||||
idx = find_first_zero_bit(ctrl->host_route_use_bm, MAX_HOST_ROUTES);
|
||||
if (idx >= MAX_HOST_ROUTES) {
|
||||
dev_err(ctrl->dev, "host route table full, %d entries in use\n",
|
||||
MAX_HOST_ROUTES);
|
||||
mutex_unlock(ctrl->lock);
|
||||
return NULL;
|
||||
}
|
||||
dev_dbg(ctrl->dev, "id: %d, ip %pI4\n", idx, &ip);
|
||||
|
||||
r = kzalloc(sizeof(*r), GFP_KERNEL);
|
||||
@@ -1057,6 +1063,12 @@ static struct otto_l3_route *otto_l3_route_alloc(struct otto_l3_ctrl *ctrl, u32
|
||||
mutex_lock(ctrl->lock);
|
||||
|
||||
idx = find_first_zero_bit(ctrl->route_use_bm, MAX_ROUTES);
|
||||
if (idx >= MAX_ROUTES) {
|
||||
dev_err(ctrl->dev, "prefix route table full, %d entries in use\n",
|
||||
MAX_ROUTES);
|
||||
mutex_unlock(ctrl->lock);
|
||||
return NULL;
|
||||
}
|
||||
dev_dbg(ctrl->dev, "id: %d, ip %pI4\n", idx, &ip);
|
||||
|
||||
r = kzalloc(sizeof(*r), GFP_KERNEL);
|
||||
|
||||
Reference in new issue
Block a user