seanmonstar/httparse

User-triggerable UB in Bytes::peek_ahead bounds-check

Closed this issue · 1 comments

httparse/src/iter.rs

Lines 45 to 49 in ab76284

pub fn peek_ahead(&self, n: usize) -> Option<u8> {
// SAFETY: obtain a potentially OOB pointer that is later compared against the `self.end`
// pointer.
let ptr = unsafe { self.cursor.add(n) };
if ptr < self.end {

ptr::add has the following safety conditions:

  • If the computed offset, in bytes, is non-zero, then both the starting and resulting pointer must be either in bounds or at the end of the same allocated object. (If it is zero, then the function is always well-defined.)

  • The computed offset, in bytes, cannot overflow an isize.

  • The offset being in bounds cannot rely on “wrapping around” the address space. That is, the infinite-precision sum must fit in a usize.

This is fixable by performing the bounds-check differently.

This is probably not an actual problem with current rustc but could be in the future

Interesting!

@AaronO do you recall if ordering the compare after the add was important? It seems like we need to do it different, but just wondering before I reach for the most obvious refactor.