31 lines
1.1 KiB
Markdown
31 lines
1.1 KiB
Markdown
# netbsd-0001 — CWE-407: ifa_ifwithaddr / ifa_ifwithnet / ifa_ifwithdstaddr — O(I×A) per-packet scan
|
||
|
||
**Severity:** HIGH
|
||
**File:** `sys/net/if.c`
|
||
**Functions:** `ifa_ifwithaddr`, `ifa_ifwithnet`, `ifa_ifwithdstaddr`
|
||
**CWE:** CWE-407 Algorithmic Complexity
|
||
|
||
## Defect
|
||
|
||
`IFNET_READER_FOREACH` (I interfaces) × `IFADDR_READER_FOREACH` (A addresses per interface). O(I×A) per call. Called from `ip_dooptions()` inside `ip_input()` — per-packet on source-routed traffic.
|
||
|
||
```c
|
||
IFNET_READER_FOREACH(ifp) {
|
||
IFADDR_READER_FOREACH(ifa, ifp) {
|
||
if (ifa->ifa_addr->sa_family != af)
|
||
continue;
|
||
if (address_match(ifa->ifa_addr, addr))
|
||
return ifa;
|
||
}
|
||
}
|
||
```
|
||
|
||
**Complexity:** O(I×A) per call, called per source-routed packet in `ip_input()`.
|
||
|
||
## Scale
|
||
|
||
At I=50 interfaces, A=20 addresses each: 1,000 comparisons per packet. On a busy router, `ip_dooptions()` dominates `ip_input()` cost on source-routed streams.
|
||
|
||
## Fix
|
||
|
||
Per-AF hash table `ifaddr_hashtab[]` keyed on address bytes → `ifaddr*`. O(1) lookup replaces the nested reader-lock scan. Table updated on `ifa_insert`/`ifa_remove` which are already under `ifnet_lock`.
|