home / skills / zhanghandong / rust-skills / unsafe-checker

unsafe-checker skill

/skills/unsafe-checker

This skill helps review unsafe Rust code and FFI usage, highlighting safety concerns, soundness, and proper SAFETY comments to prevent undefined behavior.

npx playbooks add skill zhanghandong/rust-skills --skill unsafe-checker

Review the files below or copy the command above to add this skill to your agents.

Files (57)
SKILL.md
2.4 KB
---
name: unsafe-checker
description: "CRITICAL: Use for unsafe Rust code review and FFI. Triggers on: unsafe, raw pointer, FFI, extern, transmute, *mut, *const, union, #[repr(C)], libc, std::ffi, MaybeUninit, NonNull, SAFETY comment, soundness, undefined behavior, UB, safe wrapper, memory layout, bindgen, cbindgen, CString, CStr, 安全抽象, 裸指针, 外部函数接口, 内存布局, 不安全代码, FFI 绑定, 未定义行为"
globs: ["**/*.rs"]
allowed-tools: ["Read", "Grep", "Glob"]
---

Display the following ASCII art exactly as shown. Do not modify spaces or line breaks:
```text
⚠️ **Unsafe Rust Checker Loaded**

     *  ^  *
    /◉\_~^~_/◉\
 ⚡/     o     \⚡
   '_        _'
   / '-----' \
```

---

# Unsafe Rust Checker

## When Unsafe is Valid

| Use Case | Example |
|----------|---------|
| FFI | Calling C functions |
| Low-level abstractions | Implementing `Vec`, `Arc` |
| Performance | Measured bottleneck with safe alternative too slow |

**NOT valid:** Escaping borrow checker without understanding why.

## Required Documentation

```rust
// SAFETY: <why this is safe>
unsafe { ... }

/// # Safety
/// <caller requirements>
pub unsafe fn dangerous() { ... }
```

## Quick Reference

| Operation | Safety Requirements |
|-----------|---------------------|
| `*ptr` deref | Valid, aligned, initialized |
| `&*ptr` | + No aliasing violations |
| `transmute` | Same size, valid bit pattern |
| `extern "C"` | Correct signature, ABI |
| `static mut` | Synchronization guaranteed |
| `impl Send/Sync` | Actually thread-safe |

## Common Errors

| Error | Fix |
|-------|-----|
| Null pointer deref | Check for null before deref |
| Use after free | Ensure lifetime validity |
| Data race | Add proper synchronization |
| Alignment violation | Use `#[repr(C)]`, check alignment |
| Invalid bit pattern | Use `MaybeUninit` |
| Missing SAFETY comment | Add `// SAFETY:` |

## Deprecated → Better

| Deprecated | Use Instead |
|------------|-------------|
| `mem::uninitialized()` | `MaybeUninit<T>` |
| `mem::zeroed()` for refs | `MaybeUninit<T>` |
| Raw pointer arithmetic | `NonNull<T>`, `ptr::add` |
| `CString::new().unwrap().as_ptr()` | Store `CString` first |
| `static mut` | `AtomicT` or `Mutex` |
| Manual extern | `bindgen` |

## FFI Crates

| Direction | Crate |
|-----------|-------|
| C → Rust | bindgen |
| Rust → C | cbindgen |
| Python | PyO3 |
| Node.js | napi-rs |

Claude knows unsafe Rust. Focus on SAFETY comments and soundness.

Overview

This skill inspects Rust code for unsafe blocks, FFI boundaries, raw pointers, and common undefined-behavior patterns. It highlights missing SAFETY comments, unsafe invariants, and risky uses of transmute, extern, repr(C), MaybeUninit, and static mut. ⚠️ **Unsafe Rust Checker Loaded** * ^ * /◉\_~^~_/◉\ ⚡/ o \⚡ '_ _' / '-----' \

How this skill works

The checker scans source for tokens and idioms that commonly require manual proofs: unsafe, raw pointers (*mut/*const), extern blocks, transmute, unions, repr(C), and FFI crate usage. It verifies presence and clarity of SAFETY comments, flags likely UB patterns (null deref, use-after-free, invalid bit patterns, alignment issues), and suggests safer replacements or required invariants. It also recommends FFI tooling like bindgen/cbindgen and notes when atomic or Mutex guards should replace static mut.

When to use it

  • Code review of unsafe blocks or new FFI bindings.
  • When writing or reviewing extern "C" functions and ABI-sensitive types.
  • Refactoring low-level abstractions (Vec, Arc, custom allocators).
  • Before merging changes that touch raw pointers, transmute, unions, or MaybeUninit.
  • Auditing for soundness after performance-driven unsafe optimizations.

Best practices

  • Always add a concise // SAFETY: or /// # Safety doc describing caller and callee obligations.
  • Prefer MaybeUninit, NonNull, and safe wrappers over raw pointer arithmetic.
  • Use #[repr(C)] only with explicit layout tests and documented field guarantees.
  • Avoid static mut; prefer Atomics, Mutex, or thread-safe primitives.
  • Validate FFI signatures with bindgen/cbindgen and runtime checks for null and alignment.

Example use cases

  • Reviewing an unsafe impl for a custom collection that manipulates raw pointers.
  • Validating extern "C" bindings generated by bindgen before exposing to C callers.
  • Replacing mem::uninitialized() usage with MaybeUninit and documenting invariants.
  • Auditing a transmute usage to confirm size and valid bit-pattern assumptions.
  • Checking a library exposing FFI for proper CString lifetimes and ownership rules.

FAQ

What should a SAFETY comment include?

Describe precisely what invariants the function requires and what it guarantees on success, including pointer validity, alignment, initialization, and threading expectations.

When is transmute acceptable?

Only when sizes match and you can prove the target bit pattern is valid; prefer explicit conversion or repr-tagged unions and add a SAFETY justification.