Skip to content

Commit a84621d

Browse files
committed
scylla-cql: Avoid index-acces to buffer
If buffer is too short and we index past its end, code will panic. This is not desirable - we want to return errors on invalid protocol messages.
1 parent f4b3658 commit a84621d

File tree

3 files changed

+12
-13
lines changed

3 files changed

+12
-13
lines changed

scylla-cql/src/frame/frame_errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ pub enum ClusterChangeEventParseError {
307307
pub enum PreparedParseError {
308308
#[error("Malformed prepared statement's id length: {0}")]
309309
IdLengthParseError(LowLevelDeserializationError),
310+
#[error("Malformed prepared statement's id: {0}")]
311+
IdParseError(LowLevelDeserializationError),
310312
#[error("Invalid result metadata: {0}")]
311313
ResultMetadataParseError(ResultMetadataParseError),
312314
#[error("Invalid prepared metadata: {0}")]

scylla-cql/src/frame/response/result.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::frame::frame_errors::{
1414
use crate::frame::request::query::PagingStateResponse;
1515
use crate::frame::response::event::SchemaChangeEvent;
1616
use crate::frame::types;
17-
use bytes::{Buf, Bytes};
17+
use bytes::Bytes;
1818
use std::borrow::Cow;
1919
use std::fmt::Debug;
2020
use std::sync::Arc;
@@ -1229,11 +1229,10 @@ fn deser_set_keyspace(buf: &mut &[u8]) -> StdResult<SetKeyspace, SetKeyspacePars
12291229
}
12301230

12311231
fn deser_prepared(buf: &mut &[u8]) -> StdResult<Prepared, PreparedParseError> {
1232-
let id_len = types::read_short(buf)
1233-
.map_err(|err| PreparedParseError::IdLengthParseError(err.into()))?
1234-
as usize;
1235-
let id: Bytes = buf[0..id_len].to_owned().into();
1236-
buf.advance(id_len);
1232+
let id = types::read_short_bytes(buf)
1233+
.map_err(PreparedParseError::IdParseError)?
1234+
.to_owned()
1235+
.into();
12371236
let prepared_metadata =
12381237
deser_prepared_metadata(buf).map_err(PreparedParseError::PreparedMetadataParseError)?;
12391238
let (result_metadata, paging_state_response) =

scylla-cql/src/frame/types.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
use super::TryFromPrimitiveError;
44
use super::frame_errors::LowLevelDeserializationError;
55
use byteorder::{BigEndian, ReadBytesExt};
6+
use bytes::BufMut;
67
use bytes::Bytes;
78
#[cfg(test)]
89
use bytes::BytesMut;
9-
use bytes::{Buf, BufMut};
1010
use std::collections::HashMap;
1111
use std::convert::TryFrom;
1212
use std::convert::TryInto;
@@ -603,14 +603,12 @@ pub fn read_inet(buf: &mut &[u8]) -> Result<SocketAddr, LowLevelDeserializationE
603603
let len = buf.read_u8()?;
604604
let ip_addr = match len {
605605
4 => {
606-
let ret = IpAddr::from(<[u8; 4]>::try_from(&buf[0..4])?);
607-
buf.advance(4);
608-
ret
606+
let ip_bytes = read_raw_bytes(4, buf)?;
607+
IpAddr::from(<[u8; 4]>::try_from(ip_bytes)?)
609608
}
610609
16 => {
611-
let ret = IpAddr::from(<[u8; 16]>::try_from(&buf[0..16])?);
612-
buf.advance(16);
613-
ret
610+
let ip_bytes = read_raw_bytes(16, buf)?;
611+
IpAddr::from(<[u8; 16]>::try_from(ip_bytes)?)
614612
}
615613
v => return Err(LowLevelDeserializationError::InvalidInetLength(v)),
616614
};

0 commit comments

Comments
 (0)