一键导入
c-audit
Audit C code for memory safety, SIMD correctness, thread safety, and GGUF parsing security. Use when reviewing or hardening bitnet.c modules.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Audit C code for memory safety, SIMD correctness, thread safety, and GGUF parsing security. Use when reviewing or hardening bitnet.c modules.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | c-audit |
| description | Audit C code for memory safety, SIMD correctness, thread safety, and GGUF parsing security. Use when reviewing or hardening bitnet.c modules. |
| user-invocable | true |
Perform comprehensive security, safety, and quality audits on bitnet.c C code.
Target: $ARGUMENTS (default: all src/ and include/ files)
/c-audit # Audit all source files
/c-audit src/transformer.c # Audit a specific file
/c-audit --fix # Audit and apply fixes
| Issue | Pattern to Find | Severity |
|---|---|---|
| Buffer overflow | strcpy, strcat, sprintf, gets, unbounded loops | Critical |
| Unbounded string ops | strlen, strcmp on untrusted input | Critical |
| Unsafe integer parsing | atoi, atol, atof (no error detection) | High |
| Integer overflow | malloc(a * b) without overflow check | Critical |
| Use-after-free | Pointer used after free() | Critical |
| Double-free | free() called twice on same pointer | Critical |
| Null dereference | Pointer used without NULL check | High |
| Uninitialized memory | Variables used before assignment | High |
| Missing null terminator | String buffer not explicitly terminated | High |
| Memory leak | malloc/calloc without corresponding free | Medium |
| Unsafe VLA | VLA sized by model config without BN_MAX_VLA_ELEMS guard | High |
| Stack overflow | Large stack arrays > 32KB | Medium |
Safe Replacements:
// Copying
strcpy(dst, src) -> snprintf(dst, sizeof(dst), "%s", src);
// Formatting
sprintf(buf, fmt, ...) -> snprintf(buf, sizeof(buf), fmt, ...);
// Memory allocation (overflow-safe)
malloc(count * size) -> calloc(count, size);
// Integer parsing
atoi(str) -> strtol(str, &end, 10) with validation
// VLA guards (all VLAs sized by model config MUST be guarded)
float arr[dim]; -> if (dim > BN_MAX_VLA_ELEMS) return -1;
float arr[dim];
Arena vs Direct Allocation:
// RunState buffers use SHArena (freed as a block in model_free)
float *buf = sh_arena_alloc(arena, n * sizeof(float));
// Temporary allocations during init may use malloc/free
// Verify: every malloc has a matching free on ALL paths (including error paths)
Model files are untrusted input. GGUF parsing must be defensive.
| Issue | What to Check | Severity |
|---|---|---|
| Tensor data OOB | Tensor offset + size exceeds file size | Critical |
| Integer overflow in tensor size | dims[0] * dims[1] * type_size overflow | Critical |
| Excessive allocation | n_tensors or n_kv causing huge allocation | High |
| String bounds | GGUF string length exceeds remaining buffer | Critical |
| Type confusion | Tensor type validated before casting data pointer | High |
| Dimension validation | n_dims checked (1-4), dimensions non-negative | High |
| KV lookup | gguf_find_* return values checked for not-found | Medium |
| Issue | What to Check |
|---|---|
| Token bounds | Token validated against vocab_size before embedding lookup |
| Position bounds | Position validated against seq_len |
| Array indices | All array indices validated before access |
| Pointer validity | NULL checks before dereference |
| Size parameters | Non-negative, within reasonable bounds |
| Model config | Dimensions checked before VLA allocation |
| Issue | What to Check | Severity |
|---|---|---|
| Alignment | NEON vld1q_* doesn't require alignment, but __attribute__((aligned)) arrays should be verified | Medium |
| Remainder handling | Loops assume dimension is multiple of vector width (4/8/16) — verify model guarantees this | High |
| Type punning | vreinterpret* casts between signed/unsigned verified correct | Medium |
| Out-of-bounds SIMD load | Last vector load may read past array if size not aligned | High |
| Backend consistency | NEON, AVX2, WASM, scalar backends produce equivalent results | High |
| Prefetch safety | __builtin_prefetch on valid addresses only | Low |
SIMD remainder pattern:
// GOOD: dimension guaranteed multiple of 4 by model config
for (int i = 0; i < dim; i += 4)
vst1q_f32(out + i, vmulq_f32(vld1q_f32(x + i), scale));
// BAD: no remainder handling for arbitrary sizes
// If size may not be multiple of vector width, add scalar tail:
for (; i < size; i++) out[i] = x[i] * ss;
| Issue | What to Check | Severity |
|---|---|---|
| Data races | Range functions only write to their assigned range [start, end) | Critical |
| Shared state | Context structs are read-only during dispatch (except output arrays) | Critical |
| VLA in threads | VLAs in range functions are thread-local (stack) — verify no shared scratch | High |
| Pool NULL | bn_tp_dispatch(NULL, ...) falls back to serial correctly | Medium |
| Task count | task.n matches the actual iteration space | High |
Thread safety pattern:
// GOOD: each thread writes only its range
void my_range(void *ctx, int start, int end) {
MyCtx *c = ctx;
for (int i = start; i < end; i++)
c->out[i] = compute(c, i); // out[i] is disjoint per thread
}
// BAD: shared accumulator without atomics
void bad_range(void *ctx, int start, int end) {
MyCtx *c = ctx;
for (int i = start; i < end; i++)
c->total += c->data[i]; // RACE CONDITION
}
Overflow in size computations can cause undersized allocations.
// BAD: overflow on 32-bit
int total = num_layers * seq_len * kv_dim * sizeof(float);
// GOOD: use size_t throughout
size_t total = (size_t)num_layers * seq_len * kv_dim * sizeof(float);
// GOOD: check before multiply
if (count > 0 && (size_t)count > SIZE_MAX / elem_size) {
return -1; // overflow
}
Key areas in bitnet.c:
n_attn_layers * seq_len * kv_dim)n_ssm * num_v_heads * head_k_dim * head_v_dim)vocab_size * dim)| Issue | What to Check |
|---|---|
| Model lifecycle | bn_model_load paired with bn_model_free |
| File mapping | bn_mapped_file_open paired with bn_mapped_file_close |
| Thread pool | bn_tp_create paired with bn_tp_free |
| Arena | sh_arena_create paired with sh_arena_free |
| GGUF parsing | BnGGUFFile resources freed after use |
| Error paths | Resources freed on all exit paths in model_load |
Check test files (test/test_*.c) for:
test_safety.c)| Pattern | Issue | Fix |
|---|---|---|
if (0) { ... } | Dead branch | Remove |
return; code_after; | Unreachable code | Remove |
#if 0 ... #endif | Disabled code | Remove or document |
#ifdef DEBUG blocks | Debug-only code | Keep minimal, remove file dumps |
Unused #define | Dead macro | Remove |
| Unused static function | Dead function | Remove |
Stale (void)var; casts | Suppressed warnings for removed code | Remove |
Development build (make debug):
-DDEBUG -g -O0
Sanitizer build (make asan):
-fsanitize=address,undefined -g -O0 -fno-omit-frame-pointer
Production build (make):
-O3 -Wall -Wextra -Wshadow -std=c11
Audit Checks:
-Wall -Wextra -Wshadow in production CFLAGSmake debug)make asan)make avx2-check)When /c-audit is invoked:
Locate Files
$ARGUMENTS specifies files, audit thosesrc/*.c, src/quant/*.c, src/transformer/*.c, include/*.h, test/test_*.c, MakefileScan for Critical Issues
strcpy, sprintf, gets, strcat, atoi, atolmalloc/calloc without NULL checksize_t casts)BN_MAX_VLA_ELEMS guardReview GGUF Parsing
Check Thread Safety
[start, end) of outputCheck SIMD Consistency
Check Resource Management
_init()/_create()/_load() has matching _free()/_close()model_load free partial stateDetect Dead Code
#ifdef blocksCheck Build Hardening
-Wall -Wextra -Wshadow — verify zero warningsmake avx2-check for cross-compileGenerate Report Format as markdown table with findings, severity, file:line, and suggested fix.
## C Audit Report: bitnet.c
**Date:** YYYY-MM-DD
**Files Scanned:** N
**Issues Found:** N (Critical: N, High: N, Medium: N, Low: N)
### Critical Issues
| # | File:Line | Issue | Current Code | Suggested Fix |
|---|-----------|-------|--------------|---------------|
| C1 | src/foo.c:42 | Buffer overflow | `strcpy(buf, src)` | `snprintf(buf, sizeof(buf), "%s", src)` |
### High Issues
...
### Medium Issues
...
### Low Issues
...
### Recommendations
1. ...
When --fix is specified:
make clean && make)make test)Auto-fixable Issues:
strcpy -> snprintf with buffer sizesprintf -> snprintf with buffer sizeatoi -> strtol with validationsize_t cast or overflow checkBN_MAX_VLA_ELEMS checkNOT Auto-fixable (require manual review):