Add: windows mvp - transparent bugs not fixed

This commit is contained in:
DaZuo0122
2026-02-12 22:58:33 +08:00
commit 61825f647d
147 changed files with 28498 additions and 0 deletions

View File

@@ -0,0 +1,253 @@
# Common Unsafe Pitfalls and Fixes
A reference of frequently encountered unsafe bugs and how to fix them.
## Pitfall 1: Dangling Pointer from Local
**Bug:**
```rust
fn bad() -> *const i32 {
let x = 42;
&x as *const i32 // Dangling after return!
}
```
**Fix:**
```rust
fn good() -> Box<i32> {
Box::new(42) // Heap allocation lives beyond function
}
// Or return the value itself
fn better() -> i32 {
42
}
```
## Pitfall 2: CString Lifetime
**Bug:**
```rust
fn bad() -> *const c_char {
let s = CString::new("hello").unwrap();
s.as_ptr() // Dangling! CString dropped
}
```
**Fix:**
```rust
fn good(s: &CString) -> *const c_char {
s.as_ptr() // Caller keeps CString alive
}
// Or take ownership
fn also_good(s: CString) -> *const c_char {
s.into_raw() // Caller must free with CString::from_raw
}
```
## Pitfall 3: Vec set_len with Uninitialized Data
**Bug:**
```rust
fn bad() -> Vec<String> {
let mut v = Vec::with_capacity(10);
unsafe { v.set_len(10); } // Strings are uninitialized!
v
}
```
**Fix:**
```rust
fn good() -> Vec<String> {
let mut v = Vec::with_capacity(10);
for _ in 0..10 {
v.push(String::new());
}
v
}
// Or use resize
fn also_good() -> Vec<String> {
let mut v = Vec::new();
v.resize(10, String::new());
v
}
```
## Pitfall 4: Reference to Packed Field
**Bug:**
```rust
#[repr(packed)]
struct Packed { a: u8, b: u32 }
fn bad(p: &Packed) -> &u32 {
&p.b // UB: misaligned reference!
}
```
**Fix:**
```rust
fn good(p: &Packed) -> u32 {
unsafe { std::ptr::addr_of!(p.b).read_unaligned() }
}
```
## Pitfall 5: Mutable Aliasing Through Raw Pointers
**Bug:**
```rust
fn bad() {
let mut x = 42;
let ptr1 = &mut x as *mut i32;
let ptr2 = &mut x as *mut i32; // Already have ptr1!
unsafe {
*ptr1 = 1;
*ptr2 = 2; // Aliasing mutable pointers!
}
}
```
**Fix:**
```rust
fn good() {
let mut x = 42;
let ptr = &mut x as *mut i32;
unsafe {
*ptr = 1;
*ptr = 2; // Same pointer, sequential access
}
}
```
## Pitfall 6: Transmute to Wrong Size
**Bug:**
```rust
fn bad() {
let x: u32 = 42;
let y: u64 = unsafe { std::mem::transmute(x) }; // UB: size mismatch!
}
```
**Fix:**
```rust
fn good() {
let x: u32 = 42;
let y: u64 = x as u64; // Use conversion
}
```
## Pitfall 7: Invalid Enum Discriminant
**Bug:**
```rust
#[repr(u8)]
enum Status { A = 0, B = 1, C = 2 }
fn bad(raw: u8) -> Status {
unsafe { std::mem::transmute(raw) } // UB if raw > 2!
}
```
**Fix:**
```rust
fn good(raw: u8) -> Option<Status> {
match raw {
0 => Some(Status::A),
1 => Some(Status::B),
2 => Some(Status::C),
_ => None,
}
}
```
## Pitfall 8: FFI Panic Unwinding
**Bug:**
```rust
#[no_mangle]
extern "C" fn callback(x: i32) -> i32 {
if x < 0 {
panic!("negative!"); // UB: unwinding across FFI!
}
x * 2
}
```
**Fix:**
```rust
#[no_mangle]
extern "C" fn callback(x: i32) -> i32 {
std::panic::catch_unwind(|| {
if x < 0 {
panic!("negative!");
}
x * 2
}).unwrap_or(-1) // Return error code on panic
}
```
## Pitfall 9: Double Free from Clone + into_raw
**Bug:**
```rust
struct Handle(*mut c_void);
impl Clone for Handle {
fn clone(&self) -> Self {
Handle(self.0) // Both now "own" same pointer!
}
}
impl Drop for Handle {
fn drop(&mut self) {
unsafe { free(self.0); } // Double free when both drop!
}
}
```
**Fix:**
```rust
struct Handle(*mut c_void);
// Don't implement Clone, or implement proper reference counting
impl Handle {
fn clone_ptr(&self) -> *mut c_void {
self.0 // Return raw pointer, no ownership
}
}
```
## Pitfall 10: Forget Doesn't Run Destructors
**Bug:**
```rust
fn bad() {
let guard = lock.lock();
std::mem::forget(guard); // Lock never released!
}
```
**Fix:**
```rust
fn good() {
let guard = lock.lock();
// Let guard drop naturally
// or explicitly: drop(guard);
}
```
## Quick Reference Table
| Pitfall | Detection | Fix |
|---------|-----------|-----|
| Dangling pointer | Miri | Extend lifetime or heap allocate |
| Uninitialized read | Miri | Use MaybeUninit properly |
| Misaligned access | Miri, UBsan | read_unaligned, copy by value |
| Data race | TSan | Use atomics or mutex |
| Double free | ASan | Track ownership carefully |
| Invalid enum | Manual review | Use TryFrom |
| FFI panic | Testing | catch_unwind |
| Type confusion | Miri | Match types exactly |