java-topology/defects/hurd/hurd-0005.md

2 KiB
Raw Blame History

hurd-0005 — CWE-407: _ports_bucket_class_iterate — O(total_ports) global scan [PATCHED]

Severity: MEDIUM File: libports/bucket-iterate.c lines ~4180 Function: _ports_bucket_class_iterate (called as ports_class_iterate) CWE: CWE-407 Algorithmic Complexity

Defect

When used as ports_class_iterate, scans the global _ports_htable (all ports in all buckets) and filters by class pointer. The source file itself carries:

/* This is obscenely ineffecient. ihash and ports need to cooperate
   more closely to do it efficiently. */
HURD_IHASH_ITERATE (ht, arg) {
  struct port_info *const pi = arg;
  if (class == 0 || pi->class == class)   // O(1) pointer compare after O(total_ports) walk
    { refcounts_ref(...); p[n] = pi; n++; }
}

Complexity: O(total_ports) even when only a small class subset is needed.

Scale

Total ports in a busy Hurd system: potentially thousands (one per open file descriptor, translator instance, network connection). ports_class_iterate is called during inhibit/resume operations — exactly when the system is under load.

Fix

Maintain a per-class linked list or per-class hash table in port_class. ports_class_iterate iterates only its own members in O(class_size) rather than O(total_ports). This is what the source comment already asks for.

Patch

patch/0003-CWE-407-hurd-0005-per-class-port-list.patch

  • port_info: added class_next / class_prevp intrusive list fields
  • port_class: added class_ports head pointer
  • create-internal.c + import-port.c: prepend to class list under _ports_htable_lock wrlock
  • complete-deallocate.c: splice out of class list under same wrlock
  • bucket-iterate.c: class-path walks class->class_ports in O(class_size); NULL-class (bucket iterate) still uses HURD_IHASH_ITERATE
  • Upper-bound malloc uses ht->nr_items (always ≥ class size) to avoid race with class->count (updated under separate _ports_lock after htable_lock released)