Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit f764703

Browse files
committed
removes raw indexing into packet data
Packets are at the boundary of the system where, vast majority of the time, they are received from an untrusted source. Raw indexing into the data buffer can open attack vectors if the offsets are invalid. Validating offsets beforehand is verbose and error prone. The commit updates Packet::data() api to take a SliceIndex and always to return an Option. The call-sites are so forced to explicitly handle the case where the offsets are invalid.
1 parent 8806845 commit f764703

File tree

15 files changed

+134
-94
lines changed

15 files changed

+134
-94
lines changed

bench-streamer/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ fn producer(addr: &SocketAddr, exit: Arc<AtomicBool>) -> JoinHandle<()> {
3737
for p in packet_batch.iter() {
3838
let a = p.meta.socket_addr();
3939
assert!(p.meta.size <= PACKET_DATA_SIZE);
40-
send.send_to(p.data(), &a).unwrap();
40+
let data = p.data(..).unwrap_or_default();
41+
send.send_to(data, &a).unwrap();
4142
num += 1;
4243
}
4344
assert_eq!(num, 10);

core/src/banking_stage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ impl BankingStage {
508508
.iter()
509509
.filter_map(|p| {
510510
if !p.meta.forwarded() && data_budget.take(p.meta.size) {
511-
Some(p.data().to_vec())
511+
Some(p.data(..)?.to_vec())
512512
} else {
513513
None
514514
}

core/src/packet_hasher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Default for PacketHasher {
2626

2727
impl PacketHasher {
2828
pub(crate) fn hash_packet(&self, packet: &Packet) -> u64 {
29-
self.hash_data(packet.data())
29+
self.hash_data(packet.data(..).unwrap_or_default())
3030
}
3131

3232
pub(crate) fn hash_shred(&self, shred: &Shred) -> u64 {

core/src/serve_repair.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ mod tests {
814814
.into_iter()
815815
.filter_map(|p| {
816816
assert_eq!(repair_response::nonce(p).unwrap(), nonce);
817-
Shred::new_from_serialized_shred(p.data().to_vec()).ok()
817+
Shred::new_from_serialized_shred(p.data(..).unwrap().to_vec()).ok()
818818
})
819819
.collect();
820820
assert!(!rv.is_empty());
@@ -898,7 +898,7 @@ mod tests {
898898
.into_iter()
899899
.filter_map(|p| {
900900
assert_eq!(repair_response::nonce(p).unwrap(), nonce);
901-
Shred::new_from_serialized_shred(p.data().to_vec()).ok()
901+
Shred::new_from_serialized_shred(p.data(..).unwrap().to_vec()).ok()
902902
})
903903
.collect();
904904
assert_eq!(rv[0].index(), 1);
@@ -1347,7 +1347,7 @@ mod tests {
13471347

13481348
fn verify_responses<'a>(request: &ShredRepairType, packets: impl Iterator<Item = &'a Packet>) {
13491349
for packet in packets {
1350-
let shred_payload = packet.data().to_vec();
1350+
let shred_payload = packet.data(..).unwrap().to_vec();
13511351
let shred = Shred::new_from_serialized_shred(shred_payload).unwrap();
13521352
request.verify_response(&shred);
13531353
}

core/src/unprocessed_packet_batches.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,14 @@ pub fn deserialize_packets<'a>(
355355

356356
/// Read the transaction message from packet data
357357
pub fn packet_message(packet: &Packet) -> Result<&[u8], DeserializedPacketError> {
358-
let (sig_len, sig_size) =
359-
decode_shortu16_len(packet.data()).map_err(DeserializedPacketError::ShortVecError)?;
358+
let (sig_len, sig_size) = packet
359+
.data(..)
360+
.and_then(|bytes| decode_shortu16_len(bytes).ok())
361+
.ok_or(DeserializedPacketError::ShortVecError(()))?;
360362
sig_len
361363
.checked_mul(size_of::<Signature>())
362364
.and_then(|v| v.checked_add(sig_size))
363-
.and_then(|msg_start| packet.data().get(msg_start..))
365+
.and_then(|msg_start| packet.data(msg_start..))
364366
.ok_or(DeserializedPacketError::SignatureOverflowed(sig_size))
365367
}
366368

core/src/window_service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ where
363363
inc_new_counter_debug!("streamer-recv_window-invalid_or_unnecessary_packet", 1);
364364
return None;
365365
}
366-
let serialized_shred = packet.data().to_vec();
366+
let serialized_shred = packet.data(..)?.to_vec();
367367
let shred = Shred::new_from_serialized_shred(serialized_shred).ok()?;
368368
if !shred_filter(&shred, working_bank.clone(), last_root) {
369369
return None;

gossip/tests/gossip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pub fn cluster_info_retransmit() {
260260
let retransmit_peers: Vec<_> = peers.iter().collect();
261261
retransmit_to(
262262
&retransmit_peers,
263-
p.data(),
263+
p.data(..).unwrap(),
264264
&tn1,
265265
false,
266266
&SocketAddrSpace::Unspecified,

ledger/src/shred.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,15 @@ pub fn get_shred_slot_index_type(
575575
}
576576
};
577577

578-
let shred_type = match ShredType::try_from(p.data()[OFFSET_OF_SHRED_TYPE]) {
579-
Err(_) => {
578+
let shred_type = match p
579+
.data(OFFSET_OF_SHRED_TYPE)
580+
.and_then(|shred_type| ShredType::try_from(*shred_type).ok())
581+
{
582+
None => {
580583
stats.bad_shred_type += 1;
581584
return None;
582585
}
583-
Ok(shred_type) => shred_type,
586+
Some(shred_type) => shred_type,
584587
};
585588
Some((slot, index, shred_type))
586589
}
@@ -733,7 +736,7 @@ mod tests {
733736
let shred = Shred::new_from_data(10, 0, 1000, &[1, 2, 3], ShredFlags::empty(), 0, 1, 0);
734737
let mut packet = Packet::default();
735738
shred.copy_to_packet(&mut packet);
736-
let shred_res = Shred::new_from_serialized_shred(packet.data().to_vec());
739+
let shred_res = Shred::new_from_serialized_shred(packet.data(..).unwrap().to_vec());
737740
assert_matches!(
738741
shred.parent(),
739742
Err(Error::InvalidParentOffset {
@@ -898,7 +901,7 @@ mod tests {
898901
assert_eq!(shred, Shred::new_from_serialized_shred(payload).unwrap());
899902
assert_eq!(
900903
shred.reference_tick(),
901-
Shred::reference_tick_from_data(packet.data()).unwrap()
904+
Shred::reference_tick_from_data(packet.data(..).unwrap()).unwrap()
902905
);
903906
assert_eq!(Shred::get_slot_from_packet(&packet), Some(shred.slot()));
904907
assert_eq!(
@@ -939,7 +942,7 @@ mod tests {
939942
assert_eq!(shred, Shred::new_from_serialized_shred(payload).unwrap());
940943
assert_eq!(
941944
shred.reference_tick(),
942-
Shred::reference_tick_from_data(packet.data()).unwrap()
945+
Shred::reference_tick_from_data(packet.data(..).unwrap()).unwrap()
943946
);
944947
assert_eq!(Shred::get_slot_from_packet(&packet), Some(shred.slot()));
945948
assert_eq!(

ledger/src/sigverify_shreds.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ pub fn verify_shred_cpu(packet: &Packet, slot_leaders: &HashMap<u64, [u8; 32]>)
6262
};
6363
trace!("slot {}", slot);
6464
let pubkey = slot_leaders.get(&slot)?;
65-
let signature = Signature::new(packet.data().get(sig_start..sig_end)?);
65+
let signature = Signature::new(packet.data(sig_start..sig_end)?);
6666
trace!("signature {}", signature);
67-
if !signature.verify(pubkey, packet.data().get(msg_start..msg_end)?) {
67+
if !signature.verify(pubkey, packet.data(msg_start..msg_end)?) {
6868
return Some(0);
6969
}
7070
Some(1)
@@ -304,7 +304,8 @@ fn sign_shred_cpu(keypair: &Keypair, packet: &mut Packet) {
304304
let sig_start = 0;
305305
let sig_end = sig_start + size_of::<Signature>();
306306
let msg_start = sig_end;
307-
let signature = keypair.sign_message(&packet.data()[msg_start..]);
307+
let message = packet.data(msg_start..).unwrap_or_default();
308+
let signature = keypair.sign_message(message);
308309
trace!("signature {:?}", signature);
309310
packet.buffer_mut()[..sig_end].copy_from_slice(signature.as_ref());
310311
}

0 commit comments

Comments
 (0)