#!/bin/bash # check-cwe134.sh - Verify __attribute__((format)) on printf-like wrappers # # CWE-134 format string vulnerabilities are caught at compile time by # -Wformat=2 (includes -Wformat-security + -Wformat-nonliteral), BUT only # for functions annotated with __attribute__((format(printf, N, M))) or # G_GNUC_PRINTF(N, M). # # This script ensures every variadic function whose last fixed parameter # looks like a format string has the annotation. Without it, the compiler # silently ignores format misuse. # # Usage: ./check-cwe134.sh [directory] set -e DIR="${1:-src}" echo "=== CWE-134: format attribute audit ===" echo "Scanning: $DIR" echo "" ERRORS=0 # --------------------------------------------------------------------- # # Known printf-like wrappers that MUST have the attribute # # --------------------------------------------------------------------- # REQUIRED_ATTRIBUTED=( "cons_show" "cons_debug" "cons_show_error" "cons_show_padded" "log_debug" "log_info" "log_warning" "log_error" "win_print" "win_println" "win_println_indent" "win_println_va" "win_append" "win_appendln" "win_append_highlight" "win_appendln_highlight" "win_command_exec_error" ) echo "Check 1: Known wrappers must have G_GNUC_PRINTF / __attribute__((format))" echo "" for func in "${REQUIRED_ATTRIBUTED[@]}"; do HAS_ATTR=$(grep -B1 --include="*.h" -rn "void ${func}\s*(" "$DIR" 2>/dev/null \ | grep -Ec "format\(printf|G_GNUC_PRINTF" || true) if [ "$HAS_ATTR" -eq 0 ]; then echo " ❌ $func — missing format attribute" ERRORS=$((ERRORS + 1)) fi done if [ "$ERRORS" -eq 0 ]; then echo " ✅ All known wrappers annotated." fi # --------------------------------------------------------------------- # # Auto-detect new variadic functions that look like printf wrappers # # but are NOT in the known list and NOT annotated. # # Heuristic: declaration has (... const char* ..., ...) and no attribute # # --------------------------------------------------------------------- # echo "" echo "Check 2: Detect unannotated printf-like variadic declarations in headers" echo "" KNOWN_RE=$(IFS="|"; echo "${REQUIRED_ATTRIBUTED[*]}") # Find variadic declarations with a const char* / gchar* parameter followed by ...) # that do NOT have a format attribute on the preceding line NEW_ISSUES=$(grep -B1 -rn --include="*.h" \ 'const g\?char\s*\*.*,\s*\.\.\.)' "$DIR" 2>/dev/null \ | awk ' /format\(printf|G_GNUC_PRINTF/ { skip=1; next } /const g?char.*,.*\.\.\.\)/ { if (skip) { skip=0; next } print } { skip=0 } ' \ | grep -E "void\s+\w+\s*\(" \ | grep -Ev "($KNOWN_RE)" \ || true) if [ -n "$NEW_ISSUES" ]; then echo " ⚠️ Possibly unannotated new printf-like functions:" echo "" echo "$NEW_ISSUES" echo "" NEW_COUNT=$(echo "$NEW_ISSUES" | wc -l) ERRORS=$((ERRORS + NEW_COUNT)) else echo " ✅ No unannotated variadic printf-like functions found." fi # --------------------------------------------------------------------- # # Summary # # --------------------------------------------------------------------- # echo "" echo "=== Summary ===" echo "Issues: $ERRORS" echo "" if [ "$ERRORS" -gt 0 ]; then echo "Fix: add the attribute before the declaration in the .h file:" echo " G_GNUC_PRINTF(N, M) // N = format arg, M = first vararg" echo " void my_func(ProfWin* w, const char* fmt, ...);" echo "" echo "The compiler flag -Wformat=2 will then catch all misuse automatically." exit 1 fi exit 0