Skip to content

Size issue in HeaderMap::reserve() #352

Closed
@Qwaz

Description

@Qwaz

http/src/header/map.rs

Lines 622 to 640 in 9c05e39

pub fn reserve(&mut self, additional: usize) {
// TODO: This can't overflow if done properly... since the max # of
// elements is u16::MAX.
let cap = self.entries.len()
.checked_add(additional)
.expect("reserve overflow");
if cap > self.indices.len() {
let cap = cap.next_power_of_two();
if self.entries.len() == 0 {
self.mask = cap - 1;
self.indices = vec![Pos::none(); cap].into_boxed_slice();
self.entries = Vec::with_capacity(usable_capacity(cap));
} else {
self.grow(cap);
}
}
}

usize::next_power_of_two() method silently overflows to 0 in release mode. This makes it possible to shrink the size of the map to 0 with HeaderMap::reserve().

  • If the map doesn't contain any entry, it sets the mask value to usize::MAX which is inconsistent but doesn't create any immediate harm.
  • If the map contains any entry, the code will call self.grow(0) and start infinite probing in this line.

Another problem is that the assertion for MAX_SIZE doesn't exist here, so it is possible to grow the map larger than MAX_SIZE.

Demonstration

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-headersArea: HTTP headersE-easyEffort: easy. Start here :DS-bugSeverity: bug. Something is wrong!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions