Skip to content

Commit

Permalink
Add some missing bounds checks. (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
goffrie authored and carllerche committed Apr 23, 2018
1 parent 040f391 commit 11f9141
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
15 changes: 14 additions & 1 deletion src/frame/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ impl Headers {

// Read the padding length
if flags.is_padded() {
// TODO: Ensure payload is sized correctly
if src.len() < 1 {
return Err(Error::MalformedMessage);
}
pad = src[0] as usize;

// Drop the padding
Expand All @@ -162,6 +164,9 @@ impl Headers {

// Read the stream dependency
let stream_dep = if flags.is_priority() {
if src.len() < 5 {
return Err(Error::MalformedMessage);
}
let stream_dep = StreamDependency::load(&src[..5])?;

if stream_dep.dependency_id() == head.stream_id() {
Expand Down Expand Up @@ -290,13 +295,21 @@ impl PushPromise {

// Read the padding length
if flags.is_padded() {
if src.len() < 1 {
return Err(Error::MalformedMessage);
}

// TODO: Ensure payload is sized correctly
pad = src[0] as usize;

// Drop the padding
let _ = src.split_to(1);
}

if src.len() < 5 {
return Err(Error::MalformedMessage);
}

let (promised_id, _) = StreamId::parse(&src[..4]);
// Drop promised_id bytes
let _ = src.split_to(5);
Expand Down
5 changes: 4 additions & 1 deletion src/hpack/header.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::DecoderError;
use super::{DecoderError, NeedMore};

use bytes::Bytes;
use http::{Method, StatusCode};
Expand Down Expand Up @@ -60,6 +60,9 @@ impl Header<Option<HeaderName>> {

impl Header {
pub fn new(name: Bytes, value: Bytes) -> Result<Header, DecoderError> {
if name.len() == 0 {
return Err(DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream));
}
if name[0] == b':' {
match &name[1..] {
b"authority" => {
Expand Down
2 changes: 1 addition & 1 deletion src/proto/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ where
// but should allow continuing to process current streams
// until they are all EOS. Once they are, State should
// transition to GoAway.
self.streams.recv_go_away(&frame);
self.streams.recv_go_away(&frame)?;
self.error = Some(frame.reason());
},
Some(Ping(frame)) => {
Expand Down
15 changes: 14 additions & 1 deletion src/proto/streams/streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ where
last_processed_id
}

pub fn recv_go_away(&mut self, frame: &frame::GoAway) {
pub fn recv_go_away(&mut self, frame: &frame::GoAway) -> Result<(), RecvError> {
let mut me = self.inner.lock().unwrap();
let me = &mut *me;

Expand All @@ -322,6 +322,17 @@ where
let last_stream_id = frame.last_stream_id();
let err = frame.reason().into();

if last_stream_id > actions.recv.max_stream_id() {
// The remote endpoint sent a `GOAWAY` frame indicating a stream
// that we never sent, or that we have already terminated on account
// of previous `GOAWAY` frame. In either case, that is illegal.
// (When sending multiple `GOAWAY`s, "Endpoints MUST NOT increase
// the value they send in the last stream identifier, since the
// peers might already have retried unprocessed requests on another
// connection.")
return Err(RecvError::Connection(Reason::PROTOCOL_ERROR));
}

actions.recv.go_away(last_stream_id);

me.store
Expand All @@ -337,6 +348,8 @@ where
.unwrap();

actions.conn_error = Some(err);

Ok(())
}

pub fn recv_eof(&mut self) {
Expand Down

0 comments on commit 11f9141

Please sign in to comment.