@@ -19,21 +19,37 @@ use solana_lints::{paths, utils::visit_expr_no_bodies};
19
19
use if_chain:: if_chain;
20
20
21
21
dylint_linting:: impl_late_lint! {
22
- /// **What it does:**
23
- ///
24
- /// **Why is this bad?**
25
- ///
26
- /// **Known problems:** When only one enum is serialized, may miss certain edge cases.
22
+ /// **What it does:** Checks that all deserialized types have a proper discriminant so that
23
+ /// all types are guaranteed to deserialize differently.
24
+
25
+ /// Instead of searching for equivalent types and checking to make sure those specific
26
+ /// types have a discriminant, this lint takes a more strict approach and instead enforces
27
+ /// all deserialized types it collects, to have a discriminant, regardless of whether the
28
+ /// types are equivalent or not.
29
+
30
+ /// We define a proper discriminant as an enum with as many variants as there are struct
31
+ /// types in the program. Further, the discriminant should be the first field of every
32
+ /// struct in order to avoid overwrite by arbitrary length fields, like vectors.
33
+
34
+ /// A second case of a proper discriminant is when a single enum contains as variants all the struct
35
+ /// types that will be deserialized. This "umbrella" enum essentially has a built-in
36
+ /// discriminant. If it is the only type that is deserialized, then all struct types
37
+ /// are guaranteed to be unique since the program will have to match a specific variant.
27
38
///
28
- /// **Example:**
39
+ /// **Why is this bad?**
40
+ /// The type cosplay issue is when one account type can be substituted for another account type.
41
+ /// This occurs when a type deserializes exactly the same as another type, such that you can't
42
+ /// tell the difference between deserialized type `X` and deserialized type `Y`. This allows a
43
+ /// malicious user to substitute `X` for `Y` or vice versa, and the code may perform unauthorized
44
+ /// actions with the bytes.
29
45
///
30
- /// ```rust
31
- /// // example code where a warning is issued
32
- /// ```
33
- /// Use instead:
34
- /// ```rust
35
- /// // example code that does not raise a warning
36
- /// ```
46
+ /// **Known problems:** In the case when only one enum is deserialized, this lint by default
47
+ /// regards that as secure. However, this is not always the case. For example, if the program
48
+ /// defines another enum and serializes, but never deserializes it, a user could create this enum,
49
+ /// and, if it deserializes the same as the first enum, then this may be a possible vulnerability.
50
+
51
+ /// Furthermore, one may have alternative definitions of a discriminant, such as using a bool,
52
+ /// or u8, and not an enum. This will flag a false positive.
37
53
pub TYPE_COSPLAY ,
38
54
Warn ,
39
55
"type is equivalent to another type" ,
0 commit comments