Skip to content

Potential hash-flooding DoS risk in generic hashtable with attacker-controlled keys #119

Description

@3em0

Summary

The generic ZPL_TABLE hashtable implementation assigns buckets with key % zpl_array_count(h->hashes). If a downstream application inserts attacker-controlled numeric keys directly into this table, an attacker can choose many distinct keys with the same modulo bucket and force long per-bucket chains.

This is an algorithmic-complexity denial-of-service risk for applications that expose the table key to untrusted input. I did not find an in-repository application path that directly accepts untrusted input into this table; this report is about the generic API behavior and downstream risk.

Affected Code

  • code/header/essentials/collections/hashtable.h
  • Function generated by ZPL_TABLE_DEFINE: <prefix>_find

Relevant behavior:

r.hash_index = key % zpl_array_count(h->hashes);
r.entry_index = h->hashes[r.hash_index];
while (r.entry_index >= 0) {
    if (h->entries[r.entry_index].key == key) return r;
    r.entry_prev = r.entry_index;
    r.entry_index = h->entries[r.entry_index].next;
}

Reproduction Concept

  1. Instantiate a table with ZPL_TABLE.
  2. Initialize it and use a known bucket count, for example by calling rehash to B.
  3. Insert many distinct keys of the form offset + i * B.
  4. All of these keys map to the same bucket because (offset + i * B) % B == offset.
  5. Each insert/lookup in that bucket walks an increasingly long linked chain.

Expected complexity under this pattern:

  • Lookup for a colliding absent key: O(n)
  • Insertion of many colliding keys: approximately O(n^2) total work

Impact

In a service that uses this table with attacker-controlled numeric keys, a single client can cause excessive CPU work by submitting many colliding keys. With enough requests, this can degrade service availability.

Notes

This is not a full-key equality confusion bug: _find compares the complete zpl_u64 key before returning a match. Distinct colliding keys remain distinct entries. The risk is collision-chain amplification caused by predictable modulo bucket assignment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions