Skip to content

Commit 3616cc6

Browse files
domenukktokatoka
andauthored
Fix unsafe_stable_anymap, rename to stable_anymap (it's safe) (#2338)
* doesn't work poc * Works * make this work with or without feature * start time * Fix fixes * Fix more build * fix build * reset changes in fuzzbench fuzzer --------- Co-authored-by: Toka <tokazerkje@outlook.com>
1 parent abdb7c2 commit 3616cc6

File tree

4 files changed

+60
-70
lines changed

4 files changed

+60
-70
lines changed

libafl/src/state/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ where
10811081
rand,
10821082
executions: 0,
10831083
imported: 0,
1084-
start_time: Duration::from_millis(0),
1084+
start_time: libafl_bolts::current_time(),
10851085
metadata: SerdeAnyMap::default(),
10861086
named_metadata: NamedSerdeAnyMap::default(),
10871087
corpus,

libafl_bolts/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ xxh3 = ["xxhash-rust"]
6565

6666
## With this feature, the AnyMap uses [`type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html)
6767
## instead of [`TypeId::of`](https://doc.rust-lang.org/std/any/struct.TypeId.html#method.of) for deserialization.
68-
## With this feature, stored state may remain deserializable across multiple compilations of LibAFL.
69-
## This is **unsafe** and may lead to type confusions. Only use when you know what you are doing/ you have tests in place.
70-
## The rust doc specifically states that "multiple types may map to the same type name"!
71-
unsafe_stable_anymap = []
68+
## With this feature, stored state remains deserializable across multiple compilations of LibAFL.
69+
## The rust doc specifically states that "multiple types may map to the same type name", so it could potentially lead to bugs.
70+
## However, we make sure that no two types with the same name ever exist.
71+
stable_anymap = []
7272

7373
## Automatically register all `#[derive(SerdeAny)]` types at startup.
7474
serdeany_autoreg = ["ctor"]

libafl_bolts/src/anymap.rs

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,11 @@
11
//! Poor-rust-man's downcasts to have `AnyMap`
22
3-
use alloc::boxed::Box;
43
use core::{
5-
any::{Any, TypeId},
4+
any::TypeId,
65
mem::size_of,
76
ptr::{addr_of, read_unaligned},
87
};
98

10-
/// Convert to an Any trait object
11-
pub trait AsAny: Any {
12-
/// Returns this as Any trait
13-
fn as_any(&self) -> &dyn Any;
14-
/// Returns this as mutable Any trait
15-
fn as_any_mut(&mut self) -> &mut dyn Any;
16-
/// Returns this as boxed Any trait
17-
fn as_any_boxed(self: Box<Self>) -> Box<dyn Any>;
18-
}
19-
20-
/// Implement `AsAny` for a type
21-
#[macro_export]
22-
macro_rules! impl_asany {
23-
($struct_name:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?) => {
24-
impl $(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::anymap::AsAny for $struct_name $(< $( $lt ),+ >)? {
25-
fn as_any(&self) -> &dyn ::core::any::Any {
26-
self
27-
}
28-
29-
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any {
30-
self
31-
}
32-
33-
fn as_any_boxed(
34-
self: ::alloc::boxed::Box<Self>,
35-
) -> ::alloc::boxed::Box<dyn ::core::any::Any> {
36-
self
37-
}
38-
}
39-
};
40-
}
41-
429
/// Get a `type_id` from its previously unpacked `u128`.
4310
/// Opposite of [`unpack_type_id(id)`].
4411
///

libafl_bolts/src/serdeany.rs

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,64 @@
11
//! Poor-rust-man's downcasts for stuff we send over the wire (or shared maps)
22
33
use alloc::boxed::Box;
4-
#[cfg(feature = "unsafe_stable_anymap")]
4+
#[cfg(feature = "stable_anymap")]
55
use alloc::string::{String, ToString};
6-
#[cfg(feature = "unsafe_stable_anymap")]
6+
#[cfg(feature = "stable_anymap")]
77
use core::any::type_name;
8-
#[cfg(not(feature = "unsafe_stable_anymap"))]
8+
#[cfg(not(feature = "stable_anymap"))]
99
use core::any::TypeId;
1010
use core::{any::Any, fmt::Debug};
1111

1212
use serde::{de::DeserializeSeed, Deserialize, Deserializer, Serialize, Serializer};
1313
pub use serdeany_registry::*;
1414

15-
#[cfg(not(feature = "unsafe_stable_anymap"))]
15+
#[cfg(not(feature = "stable_anymap"))]
1616
use crate::anymap::unpack_type_id;
1717

1818
/// The type of a stored type in this anymap (`u128`)
19-
#[cfg(not(feature = "unsafe_stable_anymap"))]
19+
#[cfg(not(feature = "stable_anymap"))]
2020
pub type TypeRepr = u128;
2121

2222
/// The type of a stored type in this anymap (`String`)
23-
#[cfg(feature = "unsafe_stable_anymap")]
23+
#[cfg(feature = "stable_anymap")]
2424
pub type TypeRepr = String;
2525

26-
#[cfg(not(feature = "unsafe_stable_anymap"))]
26+
#[cfg(not(feature = "stable_anymap"))]
2727
fn type_repr<T>() -> TypeRepr
2828
where
2929
T: 'static,
3030
{
3131
unpack_type_id(TypeId::of::<T>())
3232
}
3333

34-
#[cfg(not(feature = "unsafe_stable_anymap"))]
34+
#[cfg(not(feature = "stable_anymap"))]
3535
fn type_repr_owned<T>() -> TypeRepr
3636
where
3737
T: 'static,
3838
{
3939
unpack_type_id(TypeId::of::<T>())
4040
}
4141

42-
#[cfg(feature = "unsafe_stable_anymap")]
42+
#[cfg(feature = "stable_anymap")]
4343
fn type_repr_owned<T>() -> TypeRepr {
4444
type_name::<T>().to_string()
4545
}
4646

47-
#[cfg(feature = "unsafe_stable_anymap")]
47+
#[cfg(feature = "stable_anymap")]
4848
fn type_repr<T>() -> &'static str {
4949
type_name::<T>()
5050
}
5151

5252
/// A (de)serializable Any trait
5353
pub trait SerdeAny: Any + erased_serde::Serialize + Debug {
54-
/// returns this as Any trait
54+
/// Returns this type as [`Any`] trait.
5555
fn as_any(&self) -> &dyn Any;
56-
/// returns this as mutable Any trait
56+
/// Returns this as mutable [`Any`] trait.
5757
fn as_any_mut(&mut self) -> &mut dyn Any;
58-
/// returns this as boxed Any trait
58+
/// Returns this as boxed [`Any`] trait.
5959
fn as_any_boxed(self: Box<Self>) -> Box<dyn Any>;
60+
/// Returns the [`core::any::type_name`] of this type.
61+
fn type_name(&self) -> &'static str;
6062
}
6163

6264
/// Wrap a type for serialization
@@ -129,7 +131,8 @@ pub mod serdeany_registry {
129131
Error,
130132
};
131133

132-
/// A [`HashMap`] that maps from [`TypeRepr`] to a deserializer and its [`TypeId`].
134+
/// A [`HashMap`] that maps from [`TypeRepr`] to a deserializer and its [`TypeRepr`].
135+
/// We store the [`TypeId`] to assert we don't have duplicate types in the case of the `stable_anymap` feature.
133136
type DeserializeCallbackMap = HashMap<TypeRepr, (DeserializeCallback<dyn SerdeAny>, TypeId)>;
134137

135138
/// Visitor object used internally for the [`crate::serdeany::SerdeAny`] registry.
@@ -148,6 +151,7 @@ pub mod serdeany_registry {
148151
V: serde::de::SeqAccess<'de>,
149152
{
150153
let id: TypeRepr = visitor.next_element()?.unwrap();
154+
151155
let cb = unsafe {
152156
REGISTRY
153157
.deserializers
@@ -187,8 +191,10 @@ pub mod serdeany_registry {
187191
)
188192
});
189193

190-
#[cfg(feature = "unsafe_stable_anymap")]
191-
assert_eq!(_entry.1, TypeId::of::<T>(), "Fatal safety error: TypeId of type {} is not equals to the deserializer's TypeId for this type! Two registered types have the same type_name!", type_repr::<T>());
194+
// We assert that only one element with the given TypeId is in the map.
195+
// This is only necessary for stable_anymap where we don't directly use the TypeId, but the type_name instead.
196+
#[cfg(feature = "stable_anymap")]
197+
assert_eq!(_entry.1, TypeId::of::<T>(), "Fatal safety error: TypeId of type {} is not equal to the deserializer's TypeId for this type! Two registered types have the same type_name!", type_repr::<T>());
192198
}
193199

194200
pub fn finalize(&mut self) {
@@ -277,7 +283,7 @@ pub mod serdeany_registry {
277283
T: crate::serdeany::SerdeAny,
278284
{
279285
let type_repr = type_repr::<T>();
280-
#[cfg(not(feature = "unsafe_stable_anymap"))]
286+
#[cfg(not(feature = "stable_anymap"))]
281287
let type_repr = &type_repr;
282288

283289
self.map
@@ -293,7 +299,7 @@ pub mod serdeany_registry {
293299
T: crate::serdeany::SerdeAny,
294300
{
295301
let type_repr = type_repr::<T>();
296-
#[cfg(not(feature = "unsafe_stable_anymap"))]
302+
#[cfg(not(feature = "stable_anymap"))]
297303
let type_repr = &type_repr;
298304

299305
self.map
@@ -309,7 +315,7 @@ pub mod serdeany_registry {
309315
T: crate::serdeany::SerdeAny,
310316
{
311317
let type_repr = type_repr::<T>();
312-
#[cfg(not(feature = "unsafe_stable_anymap"))]
318+
#[cfg(not(feature = "stable_anymap"))]
313319
let type_repr = &type_repr;
314320

315321
self.map
@@ -351,7 +357,7 @@ pub mod serdeany_registry {
351357
T: crate::serdeany::SerdeAny,
352358
{
353359
let type_repr = type_repr::<T>();
354-
#[cfg(not(feature = "unsafe_stable_anymap"))]
360+
#[cfg(not(feature = "stable_anymap"))]
355361
let type_repr = &type_repr;
356362

357363
assert!(
@@ -410,7 +416,7 @@ pub mod serdeany_registry {
410416
T: crate::serdeany::SerdeAny,
411417
{
412418
let type_repr = type_repr::<T>();
413-
#[cfg(not(feature = "unsafe_stable_anymap"))]
419+
#[cfg(not(feature = "stable_anymap"))]
414420
let type_repr = &type_repr;
415421

416422
self.map.contains_key(type_repr)
@@ -458,7 +464,7 @@ pub mod serdeany_registry {
458464
T: crate::serdeany::SerdeAny,
459465
{
460466
let type_repr = type_repr::<T>();
461-
#[cfg(not(feature = "unsafe_stable_anymap"))]
467+
#[cfg(not(feature = "stable_anymap"))]
462468
let type_repr = &type_repr;
463469

464470
match self.map.get(type_repr) {
@@ -475,7 +481,7 @@ pub mod serdeany_registry {
475481
T: crate::serdeany::SerdeAny,
476482
{
477483
let type_repr = type_repr::<T>();
478-
#[cfg(not(feature = "unsafe_stable_anymap"))]
484+
#[cfg(not(feature = "stable_anymap"))]
479485
let type_repr = &type_repr;
480486

481487
match self.map.get_mut(type_repr) {
@@ -494,7 +500,7 @@ pub mod serdeany_registry {
494500
T: crate::serdeany::SerdeAny,
495501
{
496502
let type_repr = type_repr::<T>();
497-
#[cfg(not(feature = "unsafe_stable_anymap"))]
503+
#[cfg(not(feature = "stable_anymap"))]
498504
let type_repr = &type_repr;
499505

500506
match self.map.get_mut(type_repr) {
@@ -522,7 +528,7 @@ pub mod serdeany_registry {
522528
T: crate::serdeany::SerdeAny,
523529
{
524530
let type_repr = type_repr::<T>();
525-
#[cfg(not(feature = "unsafe_stable_anymap"))]
531+
#[cfg(not(feature = "stable_anymap"))]
526532
let type_repr = &type_repr;
527533

528534
#[allow(clippy::manual_map)]
@@ -548,7 +554,7 @@ pub mod serdeany_registry {
548554
T: crate::serdeany::SerdeAny,
549555
{
550556
let type_repr = type_repr::<T>();
551-
#[cfg(not(feature = "unsafe_stable_anymap"))]
557+
#[cfg(not(feature = "stable_anymap"))]
552558
let type_repr = &type_repr;
553559

554560
#[allow(clippy::manual_map)]
@@ -614,7 +620,7 @@ pub mod serdeany_registry {
614620
T: crate::serdeany::SerdeAny,
615621
{
616622
let type_repr = type_repr::<T>();
617-
#[cfg(not(feature = "unsafe_stable_anymap"))]
623+
#[cfg(not(feature = "stable_anymap"))]
618624
let type_repr = &type_repr;
619625

620626
assert!(
@@ -721,7 +727,7 @@ pub mod serdeany_registry {
721727
T: crate::serdeany::SerdeAny,
722728
{
723729
let type_repr = type_repr::<T>();
724-
#[cfg(not(feature = "unsafe_stable_anymap"))]
730+
#[cfg(not(feature = "stable_anymap"))]
725731
let type_repr = &type_repr;
726732

727733
self.map.contains_key(type_repr)
@@ -735,7 +741,7 @@ pub mod serdeany_registry {
735741
T: crate::serdeany::SerdeAny,
736742
{
737743
let type_repr = type_repr::<T>();
738-
#[cfg(not(feature = "unsafe_stable_anymap"))]
744+
#[cfg(not(feature = "stable_anymap"))]
739745
let type_repr = &type_repr;
740746

741747
match self.map.get(type_repr) {
@@ -768,9 +774,18 @@ impl Serialize for dyn crate::serdeany::SerdeAny {
768774
{
769775
use serde::ser::SerializeSeq;
770776

771-
let id = crate::anymap::unpack_type_id(self.type_id());
777+
#[cfg(not(feature = "stable_anymap"))]
778+
let type_id = crate::anymap::unpack_type_id(self.type_id());
779+
#[cfg(not(feature = "stable_anymap"))]
780+
let type_id = &type_id;
781+
782+
// For the stable anymap, we use the `type_name` as type id.
783+
// Of course this may go wrong... :)
784+
#[cfg(feature = "stable_anymap")]
785+
let type_id = self.type_name();
786+
772787
let mut seq = se.serialize_seq(Some(2))?;
773-
seq.serialize_element(&id)?;
788+
seq.serialize_element(type_id)?;
774789
seq.serialize_element(&crate::serdeany::Wrap(self))?;
775790
seq.end()
776791
}
@@ -840,6 +855,10 @@ macro_rules! impl_serdeany {
840855
) -> $crate::alloc::boxed::Box<dyn ::core::any::Any> {
841856
self
842857
}
858+
859+
fn type_name(&self) -> &'static str {
860+
core::any::type_name::<Self>()
861+
}
843862
}
844863

845864
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]
@@ -877,6 +896,10 @@ macro_rules! impl_serdeany {
877896
) -> $crate::alloc::boxed::Box<dyn ::core::any::Any> {
878897
self
879898
}
899+
900+
fn type_name(&self) -> &'static str {
901+
core::any::type_name::<Self>()
902+
}
880903
}
881904

882905
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]

0 commit comments

Comments
 (0)