diff options
Diffstat (limited to 'azalea-protocol')
| -rw-r--r-- | azalea-protocol/fuzz/.gitignore | 2 | ||||
| -rw-r--r-- | azalea-protocol/fuzz/README.md | 6 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_merchant_offers.rs | 13 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_update_advancements.rs | 6 | ||||
| -rw-r--r-- | azalea-protocol/src/read.rs | 21 |
5 files changed, 42 insertions, 6 deletions
diff --git a/azalea-protocol/fuzz/.gitignore b/azalea-protocol/fuzz/.gitignore index 1a45eee7..7a68a04b 100644 --- a/azalea-protocol/fuzz/.gitignore +++ b/azalea-protocol/fuzz/.gitignore @@ -2,3 +2,5 @@ target corpus artifacts coverage + +fuzz-*.log
\ No newline at end of file diff --git a/azalea-protocol/fuzz/README.md b/azalea-protocol/fuzz/README.md index df18e8ea..28b1cf4b 100644 --- a/azalea-protocol/fuzz/README.md +++ b/azalea-protocol/fuzz/README.md @@ -11,11 +11,13 @@ Additionally, you should be aware that this fuzzer only targets `azalea-protocol ```sh cargo install cargo-fuzz -cargo fuzz run clientbound_game -s none -- -rss_limit_mb=16384 +cargo fuzz run clientbound_game -s none -- -rss_limit_mb=16384 -malloc_limit_mb=1024 # other valid targets: {clientbound,serverbound}_{config,game,handshake,login,status} # note: the rss_limit_mb is increased (from the default of 2048) so libfuzzer # doesn't oom due to the branchiness of the code :( -# also see https://appsec.guide/docs/fuzzing/rust/cargo-fuzz/#addresssanitizer +# also, the `-s none` is there for increased performance, but at the cost of catching less bugs. feel free to remove it. + +# also see https://appsec.guide/docs/fuzzing/rust/cargo-fuzz/ ``` diff --git a/azalea-protocol/src/packets/game/c_merchant_offers.rs b/azalea-protocol/src/packets/game/c_merchant_offers.rs index 7bbf92c4..957060b4 100644 --- a/azalea-protocol/src/packets/game/c_merchant_offers.rs +++ b/azalea-protocol/src/packets/game/c_merchant_offers.rs @@ -2,6 +2,7 @@ use std::{ any::Any, fmt::{self, Debug}, io::{self, Cursor, Write}, + mem::ManuallyDrop, }; use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; @@ -54,8 +55,13 @@ impl ItemCost { pub fn into_item_stack(self) -> ItemStackData { let mut component_patch = DataComponentPatch::default(); for component in self.components.expected { + let component = ManuallyDrop::new(component); + // SAFETY: DataComponentUnion does not run any destructors unless it's dropped + // through drop_as, so since TypedDataComponent is now ManuallyDrop, the value + // will stay in memory. + let value = unsafe { std::ptr::read(&component.value) }; unsafe { - component_patch.unchecked_insert_component(component.kind, Some(component.value)); + component_patch.unchecked_insert_component(component.kind, Some(value)); } } // TODO: add a fast way to iterate over default components, and insert the ones @@ -129,6 +135,11 @@ impl Clone for TypedDataComponent { } } } +impl Drop for TypedDataComponent { + fn drop(&mut self) { + unsafe { self.value.drop_as(self.kind) }; + } +} impl PartialEq for TypedDataComponent { fn eq(&self, other: &Self) -> bool { if self.kind != other.kind { diff --git a/azalea-protocol/src/packets/game/c_update_advancements.rs b/azalea-protocol/src/packets/game/c_update_advancements.rs index 62881b9d..24baebc5 100644 --- a/azalea-protocol/src/packets/game/c_update_advancements.rs +++ b/azalea-protocol/src/packets/game/c_update_advancements.rs @@ -22,7 +22,7 @@ pub struct ClientboundUpdateAdvancements { #[derive(AzBuf, Clone, Debug, PartialEq)] pub struct Advancement { pub parent_id: Option<Identifier>, - pub display: Option<DisplayInfo>, + pub display: Option<Box<DisplayInfo>>, pub requirements: Vec<Vec<String>>, pub sends_telemetry_event: bool, } @@ -134,7 +134,7 @@ mod tests { id: Identifier::new("minecraft:test"), value: Advancement { parent_id: None, - display: Some(DisplayInfo { + display: Some(Box::new(DisplayInfo { title: FormattedText::from("title".to_owned()), description: FormattedText::from("description".to_owned()), icon: ItemStack::Empty, @@ -144,7 +144,7 @@ mod tests { background: None, x: 0.0, y: 0.0, - }), + })), requirements: Vec::new(), sends_telemetry_event: false, }, diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs index 664e2593..5ec7f3b9 100644 --- a/azalea-protocol/src/read.rs +++ b/azalea-protocol/src/read.rs @@ -406,6 +406,8 @@ where mod tests { use std::io::Cursor; + use azalea_buf::AzaleaRead as _; + use crate::{packets::game::ClientboundGamePacket, read::deserialize_packet}; #[test] @@ -433,4 +435,23 @@ mod tests { .as_slice(), )); } + #[test] + fn fuzzed_4() { + // memory leak in DataComponentPatch + let _ = deserialize_packet::<ClientboundGamePacket>(&mut Cursor::new( + [94, 94, 70, 52, 0, 6, 0].as_slice(), + )); + } + #[test] + fn fuzzed_5() { + // also a memory leak in DataComponentPatch + let _ = deserialize_packet::<ClientboundGamePacket>(&mut Cursor::new( + [94, 94, 70, 52, 0, 6, 0, 6, 0].as_slice(), + )); + } + #[test] + fn fuzzed_6() { + // memory leak in simdnbt + let _ = simdnbt::owned::Nbt::azalea_read(&mut Cursor::new([10, 10, 0, 0, 0].as_slice())); + } } |
