diff --git a/rules/S7433/metadata.json b/rules/S7433/metadata.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/rules/S7433/metadata.json @@ -0,0 +1,2 @@ +{ +} diff --git a/rules/S7433/rust/metadata.json b/rules/S7433/rust/metadata.json new file mode 100644 index 0000000000..9940f372d7 --- /dev/null +++ b/rules/S7433/rust/metadata.json @@ -0,0 +1,24 @@ +{ + "title": "Raw pointers should not be casted to slices with differently sized elements", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "clippy" + ], + "defaultSeverity": "Blocker", + "ruleSpecification": "RSPEC-7433", + "sqKey": "S7433", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } +} diff --git a/rules/S7433/rust/rule.adoc b/rules/S7433/rust/rule.adoc new file mode 100644 index 0000000000..99a9cd3dab --- /dev/null +++ b/rules/S7433/rust/rule.adoc @@ -0,0 +1,38 @@ + +== Why is this an issue? +When casting a raw pointer to a slice, the produced raw pointer does not correctly update its length metadata, leading to potential issues such as creating a slice with less data than intended or more data, risking undefined behavior upon dereferencing. + +== How to fix it + +Use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length. + +=== Code examples + +==== Noncompliant code example +[source,rust,diff-id=1,diff-type=noncompliant] +---- +let a = [1_u8, 2, 3, 4]; +let p = &a as *const [u8] as *const [u32]; +unsafe { + println!("{:?}", &*p); // Noncompliant: Undefined behavior +} +---- + +==== Compliant solution + +[source,rust,diff-id=1,diff-type=compliant] +---- +let a = [1_i32, 2, 3, 4]; +let old_ptr = &a as *const [i32]; +// The data pointer is cast to a pointer to the target `u8` not `[u8]` +// The length comes from the known length of 4 i32s times the 4 bytes per i32 +let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16); +unsafe { + println!("{:?}", &*new_ptr); +} +---- + +== Resources +=== Documentation + +* Clippy Lints - https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_different_sizes