nmap-0002 + haproxy-0004 + nginx-0004 + weechat-0003 + zeek-0002 + curl-0004: 6 new CWE-407 defects in network tools; count 693→699
nmap-0002: nmap.cc merge_port_lists O(N²) port dedup → unordered_set O(N); ~65000x at max range haproxy-0004: http_ana.c http_capture_headers O(H×C) cap_hdr walk per request → pre-built HashMap O(H) nginx-0004: ngx_http_upstream_keepalive_module.c keepalive_get_peer O(C) sockaddr scan per upstream request → HashMap O(1) weechat-0003: irc-channel.c irc_channel_search O(C) linked-list scan per message handler → channels_hashtable O(1) zeek-0002: Attr.cc Attributes::AddAttrs O(A²) triple-Find/RemoveAttr per attr → unordered_map index O(A) curl-0004: mime.c search_header O(P×H) 3x per part per mime_add_headers → pre-indexed header name set O(P)
This commit is contained in:
parent
421f3352c7
commit
ba818693db
21 changed files with 2213 additions and 0 deletions
90
defects/nmap/unit/NmapMergePortListsTest.java
Normal file
90
defects/nmap/unit/NmapMergePortListsTest.java
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* nmap-0002 — CWE-407: O(N²) port deduplication in merge_port_lists
|
||||
*
|
||||
* Models nmap.cc insert_port_into_merge_list():
|
||||
* Slow: for each port to insert, linear scan of already-merged list (O(N))
|
||||
* called N times → O(N²) total
|
||||
* Fast: unordered_set<uint16_t>: O(1) insert + dedup → O(N) total
|
||||
*
|
||||
* Trigger: nmap -PS<range> -PA<range> with large overlapping port lists.
|
||||
* Default lists are tiny (1-2 ports), but user can pass 1-65535 for both.
|
||||
*/
|
||||
public class NmapMergePortListsTest {
|
||||
|
||||
// --- SLOW: linear scan dedup (defect) ---
|
||||
static long mergePortListsSlow(int[] list1, int[] list2) {
|
||||
long ops = 0;
|
||||
List<Integer> merged = new ArrayList<>(list1.length + list2.length);
|
||||
for (int p : list1) {
|
||||
boolean found = false;
|
||||
for (int m : merged) { ops++; if (m == p) { found = true; break; } }
|
||||
if (!found) merged.add(p);
|
||||
}
|
||||
for (int p : list2) {
|
||||
boolean found = false;
|
||||
for (int m : merged) { ops++; if (m == p) { found = true; break; } }
|
||||
if (!found) merged.add(p);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// --- FAST: hash set dedup (fix) ---
|
||||
static long mergePortListsFast(int[] list1, int[] list2) {
|
||||
long ops = 0;
|
||||
Set<Integer> seen = new HashSet<>((list1.length + list2.length) * 2);
|
||||
for (int p : list1) { ops++; seen.add(p); }
|
||||
for (int p : list2) { ops++; seen.add(p); }
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("nmap-0002 CWE-407: merge_port_lists O(N²) vs O(N)");
|
||||
System.out.println("===================================================");
|
||||
|
||||
// Small test: two overlapping port lists
|
||||
int N = 500;
|
||||
int[] list1 = new int[N];
|
||||
int[] list2 = new int[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
list1[i] = i + 1; // ports 1..500
|
||||
list2[i] = i + 250; // ports 250..750 (overlap with list1)
|
||||
}
|
||||
|
||||
long slowOps = mergePortListsSlow(list1, list2);
|
||||
long fastOps = mergePortListsFast(list1, list2);
|
||||
|
||||
System.out.printf(" N=%d ports per list (250 overlap)%n", N);
|
||||
System.out.printf(" Slow (linear scan): %,d ops%n", slowOps);
|
||||
System.out.printf(" Fast (hash set): %,d ops%n", fastOps);
|
||||
System.out.printf(" Op ratio: %.0fx%n", (double) slowOps / fastOps);
|
||||
|
||||
// Larger test
|
||||
int N2 = 2000;
|
||||
int[] big1 = new int[N2];
|
||||
int[] big2 = new int[N2];
|
||||
for (int i = 0; i < N2; i++) {
|
||||
big1[i] = i + 1;
|
||||
big2[i] = i + 1000; // 1000 overlap
|
||||
}
|
||||
|
||||
long slowOps2 = mergePortListsSlow(big1, big2);
|
||||
long fastOps2 = mergePortListsFast(big1, big2);
|
||||
|
||||
System.out.printf("%n N=%d ports per list (1000 overlap)%n", N2);
|
||||
System.out.printf(" Slow (linear scan): %,d ops%n", slowOps2);
|
||||
System.out.printf(" Fast (hash set): %,d ops%n", fastOps2);
|
||||
System.out.printf(" Op ratio: %.0fx%n", (double) slowOps2 / fastOps2);
|
||||
|
||||
// Assert O(N²) vs O(N)
|
||||
assert slowOps > fastOps * (N / 2) :
|
||||
"Expected slow > fast*" + (N/2) + " but slow=" + slowOps + " fast=" + fastOps;
|
||||
assert slowOps2 > fastOps2 * (N2 / 4) :
|
||||
"Expected slow2 > fast2*" + (N2/4) + " but slow2=" + slowOps2 + " fast2=" + fastOps2;
|
||||
|
||||
System.out.println("\nPASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue