java-topology/whitepaper/outreach/wireshark.md

4.8 KiB
Raw Blame History

Wireshark — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

One algorithmic complexity defect in Wireshark's display filter engine. dfilter_interested_in_field() performs a linear scan over an int[] array of interested field IDs per color filter per captured packet, discarding a compile-time GHashTable that would provide O(1) lookup. Fix: retain the GHashTable at runtime. Patched.

The Defects

wireshark-0001 (PATCHED — HIGH): epan/dfilter/dfilter.c

/* dfilter_interested_in_field() — called per color filter per captured packet: */
gboolean dfilter_interested_in_field(dfilter_t *df, int field_id) {
    int *ptr = df->interested_fields;
    while (*ptr != -1) {            /* O(F) scan of int[] sentinel-terminated array */
        if (*ptr == field_id) return TRUE;
        ptr++;
    }
    return FALSE;
}
/* Called C times per packet (C = number of color filters with active dfilt) */
/* Total per capture: O(packets × C × F) — F = fields per dfilter */

dfilter_interested_in_field() walks a sentinel-terminated int[] array of F interested field IDs. This array is populated from a GHashTable (df->interesting_fields) that exists at dfilter compile time but is serialized to the array for "efficiency" — however, the hash table is then discarded. The array scan is O(F) vs O(1) for the hash table. The function is called for every color filter on every dissected packet. Fix: retain the GHashTable at runtime and use g_hash_table_contains() instead of the array scan.

Complexity Proof

Let F = number of interested field IDs in the display filter's interested_fields array, C = number of active color filters applied to the capture, N = number of packets in the capture session.

  • Defective: while (*ptr != -1) scans up to F entries per call.
    • Called once per color filter per packet: O(C × F) per packet.
    • Full capture: O(N × C × F) total field-interest checks.
  • Fixed: g_hash_table_contains(df->interesting_fields_set, GINT_TO_POINTER(field_id)) → O(1) per call.
    • Full capture: O(N × C) total.
    • Speedup: O(F) — linear in number of interested fields per filter.

At F=100 interested fields per color filter, C=10 active color filters, N=1,000,000 packets:

  • Defective: up to 1,000,000,000 field-id comparisons.
  • Fixed: 10,000,000 hash table lookups.
  • 100× reduction for this configuration.

The GHashTable (df->interesting_fields) already exists at compile time — it is used to populate the array. Retaining it (or rebuilding it from the array at dfilter load) is the minimum-change fix with zero functional impact.

Impact

All Wireshark users applying color filters or display filter-based column expressions to live captures or large capture files. Color filters are on by default in the Wireshark GUI. Every user with the default color filter set (10+ filters) experiences O(F) overhead per packet per filter during dissection. For capture files with millions of packets (common in network forensics and performance analysis), this compounds to billions of unnecessary array comparisons.

Wireshark is the dominant network protocol analyzer, used universally in network engineering, security research, and forensics.

The Fix

Retain df->interesting_fields (GHashTable) after dfilter compilation and use it in dfilter_interested_in_field():

/* Before */
gboolean dfilter_interested_in_field(dfilter_t *df, int field_id) {
    int *ptr = df->interested_fields;    /* int[] sentinel array */
    while (*ptr != -1) {                 /* O(F) scan — CWE-407 */
        if (*ptr == field_id) return TRUE;
        ptr++;
    }
    return FALSE;
}

/* After */
/* CWE-407 fix: retain GHashTable from compile time for O(1) lookup. */
/* In dfilter_t: add field GHashTable *interested_fields_ht; */
/* At compile finalization: keep df->interesting_fields alive (do not free). */

gboolean dfilter_interested_in_field(dfilter_t *df, int field_id) {
    return g_hash_table_contains(df->interesting_fields_ht,
                                 GINT_TO_POINTER(field_id));  /* O(1) */
}

The int[] array can be removed entirely, or kept for serialization (e.g., dfilter wire format) without being used in the hot path.

Patch

defects/wireshark/patch/wireshark-0001-dfilter-interested-fields-hashtable.patch

What We Ask

  1. Confirm receipt and assign a GitLab security advisory reference (wireshark/wireshark).
  2. Validate the patch against the dfilter and color filter test suites.
  3. Assess CVE eligibility — wireshark-0001 fires per packet per color filter; large captures amplify to billions of unnecessary comparisons.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.