huiali/rust-skills/rust-unsafe

Claude Code and agent skill by huiali/rust-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Unsafe code and FFI expert covering raw pointers (*mut, *const), FFI patterns, transmute, union, #[repr(C)], SAFETY comments, soundness rules, and undefined behavior prevention.

Install

npx vskill@latest install huiali/rust-skills/rust-unsafe

SKILL.md

When Unsafe is Justified

Use CaseExampleJustified?
FFI calls to Cextern "C" { fn libc_malloc(size: usize) -> *mut c_void; }✅ Yes
Low-level abstractionsInternal implementation of Vec, Arc✅ Yes
Performance optimization (measured)Hot path with proven bottleneck⚠️ Verify first
Escaping borrow checkerDon't know why you need it❌ No

SAFETY Comment Requirements

Every unsafe block must include a SAFETY comment:

rust
// SAFETY: ptr must be non-null and properly aligned.
// This function is only called after a null check.
unsafe { *ptr = value; }
/// # Safety
///
/// * `ptr` must be properly aligned and not null
/// * `ptr` must point to initialized memory of type T
/// * The memory must not be accessed after this function returns
pub unsafe fn write(ptr: *mut T, value: &T) { ... }

Solution Patterns

Pattern 1: FFI with Safe Wrapper
rust
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
extern "C" {
fn c_function(s: *const c_char) -> i32;
}
// ✅ Safe wrapper
pub fn safe_c_function(s: &str) -> Result<i32, Box<dyn Error>> {
let c_str = CString::new(s)?;
// SAFETY: c_str is a valid null-terminated string created from Rust data.
// The pointer is valid for the duration of this call.
let result = unsafe { c_function(c_str.as_ptr()) };
Ok(result)
}
Pattern 2: Raw Pointer with Validation
rust
use std::ptr::NonNull;
struct Buffer {
ptr: NonNull<u8>,
len: usize,
}
impl Buffer {
pub fn write(&mut self, index: usize, value: u8) -> Result<(), String> {
if index >= self.len {
return Err("index out of bounds".to_string());
}
// SAFETY: We've checked index is within bounds.
// ptr is NonNull and points to valid memory.
unsafe {
self.ptr.as_ptr().add(index).write(value);
}
Ok(())
}
}
Pattern 3: Uninitialized Memory
rust
use std::mem::MaybeUninit;
// ✅ Safe uninitialized memory handling
fn create_buffer(size: usize) -> Vec<u8> {
let mut buffer: Vec<MaybeUninit<u8>> = Vec::with_capacity(size);
for i in 0..size {
buffer.push(MaybeUninit::new(0));
}
// SAFETY: All elements have been initialized to 0.
unsafe { std::mem::transmute(buffer) }
}
// ❌ Avoid: deprecated pattern
fn bad_buffer(size: usize) -> Vec<u8> {
let mut v = Vec::with_capacity(size);
unsafe { v.set_len(size); } // UB if not initialized!
v
}
Pattern 4: Repr(C) for FFI
rust
#[repr(C)]
pub struct Point {
pub x: f64,
pub y: f64,
}
#[repr(C)]
pub enum Status {
Success = 0,
Error = 1,
}
// SAFETY: Layout matches C struct exactly
extern "C" {
fn process_point(p: *const Point) -> Status;
}

47 Unsafe Rules Reference

General Principles (3 rules)
RuleDescription
G-01Don't use unsafe to escape compiler safety checks
G-02Don't blindly use unsafe for performance
G-03Don't create "Unsafe" aliases for types/methods
Memory Layout (6 rules)
RuleDescription
M-01Choose appropriate memory layout for struct/tuple/enum
M-02Don't modify memory variables of other processes
M-03Don't let String/Vec auto-deallocate memory from other processes
M-04Prefer reentrant versions of C-API or syscalls
M-05Use third-party crates for bit fields
M-06Use MaybeUninit<T> for uninitialized memory
Raw Pointers (6 rules)
RuleDescription
P-01Don't share raw pointers across threads
P-02Prefer NonNull<T> over *mut T
P-03Use PhantomData<T> to mark variance and ownership
P-04Don't dereference pointers cast to misaligned types
P-05Don't manually convert immutable pointers to mutable
P-06Use ptr::cast instead of as for pointer casts
Unions (2 rules)
RuleDescription
U-01Avoid unions except for C interop
U-02Don't use union variants with different lifetimes
FFI (18 rules)
RuleDescription
F-01Avoid passing strings directly to C
F-02Carefully read std::ffi types documentation
F-03Implement Drop for wrapped C pointers
F-04Handle panics across FFI boundaries
F-05Use portable type aliases from std or libc
F-06Ensure C-ABI string compatibility
F-07Don't implement Drop for types passed to extern code
F-08Handle errors properly in FFI
F-09Use references instead of raw pointers in safe wrappers
F-10Exported functions must be thread-safe
F-11Be careful with references to repr(packed) fields
F-12Document invariant assumptions for C parameters
F-13Ensure consistent data layout for custom types
F-14FFI types should have stable layout
F-15Validate robustness of external values
F-16Separate data and code for C closures
F-17Use opaque types instead of c_void
F-18Avoid passing trait objects to C
Safe Abstractions (11 rules)
RuleDescription
S-01Be aware of memory safety issues from panics
S-02Unsafe code authors must verify safety invariants
S-03Don't expose uninitialized memory in public APIs
S-04Avoid double-free from panics
S-05Consider safety when manually implementing Auto Traits
S-06Don't expose raw pointers in public APIs
S-07Provide safe alternatives for performance
S-08Returning mutable reference from immutable parameter is wrong
S-09Add SAFETY comment before each unsafe block
S-10Add Safety section to public unsafe function docs
S-11Use assert! instead of debug_assert! in unsafe functions
I/O Safety (1 rule)
RuleDescription
I-01Ensure I/O safety when using raw handles

Workflow

Step 1: Question the Need
Do I really need unsafe?
→ Can I use safe abstractions?
→ Is this for FFI? (justified)
→ Is this for measured performance? (profile first)
→ Am I fighting the borrow checker? (redesign instead)
Step 2: Write SAFETY Comments
For every unsafe block:
1. Document preconditions
2. Explain why they hold
3. Reference invariants maintained
For public unsafe functions:
1. Add /// # Safety section
2. List all requirements
3. Document consequences of violations
Step 3: Validate with Tools
bash
# Detect undefined behavior
cargo +nightly miri test
# Memory leak detection
valgrind ./target/release/program
# Data race detection
RUST_BACKTRACE=1 cargo test --features tsan
Step 4: Build Safe Wrappers
Raw unsafe code
↓
Safe private functions (validate inputs)
↓
Safe public API (no unsafe visible)

Common Errors and Fixes

ErrorFix
Null pointer dereferenceCheck for null before dereferencing
Use after freeEnsure lifetime validity
Data raceAdd synchronization
Alignment violationUse #[repr(C)], check alignment
Invalid bit patternUse MaybeUninit
Missing SAFETY commentAdd comment

Deprecated Patterns

DeprecatedModern Alternative
mem::uninitialized()MaybeUninit<T>
mem::zeroed() (for reference types)MaybeUninit<T>
Raw pointer arithmeticNonNull<T>, ptr::add
CString::new().unwrap().as_ptr()Store CString first
static mutAtomicT or Mutex
Manual extern declarationsbindgen

FFI Tools

DirectionTool
C → Rustbindgen
Rust → Ccbindgen
PythonPyO3
Node.jsnapi-rs
C++cxx

Review Checklist

When reviewing unsafe code:

  • [ ] Unsafe usage is justified (FFI, low-level abstraction, measured perf)
  • [ ] Every unsafe block has SAFETY comment
  • [ ] Public unsafe functions document Safety requirements
  • [ ] Raw pointers are validated before dereferencing
  • [ ] No raw pointer sharing across threads without sync
  • [ ] FFI boundaries properly handle panics
  • [ ] Memory layout explicitly specified for FFI types
  • [ ] Uninitialized memory uses MaybeUninit
  • [ ] Safe public API wraps unsafe internals
  • [ ] Tested with Miri for undefined behavior

Verification Commands

bash
# Check for undefined behavior
cargo +nightly miri test
# Run with address sanitizer
RUSTFLAGS="-Z sanitizer=address" cargo +nightly test
# Check FFI bindings
cargo check --features ffi
# Verify memory safety
valgrind --leak-check=full ./target/release/program
# Documentation check
cargo doc --no-deps --open

Common Pitfalls

1. Dangling Pointers

Symptom: Use-after-free, segfault

rust
// ❌ Bad: pointer outlives data
fn bad() -> *const i32 {
let x = 42;
&x as *const i32 // Dangling!
}
// ✅ Good: proper lifetime management
fn good(x: &i32) -> *const i32 {
x as *const i32 // Lifetime tied to input
}
2. Uninitialized Memory

Symptom: Undefined behavior, random values

rust
// ❌ Bad: reading uninitialized memory
let x: i32;
unsafe { println!("{}", x); } // UB!
// ✅ Good: use MaybeUninit
let mut x = MaybeUninit::<i32>::uninit();
x.write(42);
let x = unsafe { x.assume_init() }; // Safe
3. Invalid Repr

Symptom: FFI crashes, data corruption

rust
// ❌ Bad: default repr with FFI
struct Point { x: f64, y: f64 }
extern "C" { fn use_point(p: Point); }
// ✅ Good: explicit C layout
#[repr(C)]
struct Point { x: f64, y: f64 }
extern "C" { fn use_point(p: Point); }

Related Skills

  • rust-ownership - Lifetime and borrowing fundamentals
  • rust-ffi - Advanced FFI patterns
  • rust-performance - When unsafe optimization is justified
  • rust-coding - SAFETY comment conventions
  • rust-concurrency - Thread-safe unsafe patterns

Localized Reference

  • Chinese version: SKILL_ZH.md - 完整中文版本,包含所有内容

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
47
Repository forks
8
7-day trend score
17

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 11 Apr 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/huiali/rust-skills/rust-unsafe/badge)](https://verified-skill.com/skills/huiali/rust-skills/rust-unsafe)

Something wrong with this skill or its page? Tell us.