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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions