Files
0xdea-semgrep-rules/rules/c/write-into-stack-buffer.yaml
2026-03-26 11:46:15 +01:00

190 lines
6.2 KiB
YAML

rules:
- id: raptor-write-into-stack-buffer
metadata:
author: Marco Ivaldi <raptor@0xdeadbeef.info>
category: security
subcategory:
- audit
vulnerability_class: Memory Issues
likelihood: LOW
impact: LOW
confidence: MEDIUM
technology:
- c
- cpp
cwe:
- "CWE-121: Stack-based Buffer Overflow"
owasp:
- A08:2025 - Software or Data Integrity Failures
references:
- https://github.com/googleprojectzero/weggli
message: >-
The software directly writes into a stack buffer. This might lead to
a stack-based buffer overflow.
severity: INFO
languages:
- c
- cpp
# NOTE: some functions (e.g., the `scanf` family) and some other ways to write into a stack buffer are not covered.
# NOTE: `memcpy_s`, `memmove_s`, `memset_explicit`, and similar variants are not covered.
# NOTE: `strcpy_s`, `strcat_s`, and similar variants are not covered.
# NOTE: global variables declared outside functions and not explicitly tagged as `static` are not supported.
# NOTE: based on `semgrep --time` output, processing of this rule seems to be particularly slow; consider disabling it, if you don't need it.
pattern-either:
# buffer in 1st arg (buffer to buffer copy functions)
- patterns:
- pattern: $FUN($BUF, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- pattern-not: $FUN($BUF, "...", ...)
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# strcpy
- pattern: strcpy
- pattern: strncpy
- pattern: stpcpy
- pattern: stpncpy
- pattern: strlcpy
- pattern: strscpy
- pattern: wcscpy
- pattern: wcsncpy
- pattern: wcpcpy
- pattern: wcpncpy
- pattern: wcslcpy
- pattern: _mbscpy
- pattern: _mbsncpy
- pattern: _mbpcpy
- pattern: _mbpncpy
- pattern: _mbslcpy
- pattern: strccpy
- pattern: strcadd
- pattern: streadd
- pattern: strecpy
# strcat
- pattern: strcat
- pattern: strncat
- pattern: strlcat
- pattern: wcscat
- pattern: wcsncat
- pattern: wcslcat
- pattern: _mbscat
- pattern: _mbsncat
- pattern: _mbslcat
# memcpy/memset
- pattern: memcpy
- pattern: memccpy
- pattern: mempcpy
- pattern: memmove
- pattern: memset
- pattern: wmemcpy
- pattern: wmempcpy
- pattern: wmemmove
- pattern: wmemset
# buffer in 1st arg (sprintf functions)
- patterns:
- pattern: $FUN($BUF, $FMT, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- metavariable-regex:
metavariable: $FMT
# some format string specifiers are not handled
regex: '(".*%l?s.*"|".*%S.*"|[a-zA-Z_][a-zA-Z0-9_]*)'
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# sprintf
- pattern: sprintf
- pattern: vsprintf
# buffer in 1st arg (snprintf functions)
- patterns:
- pattern: $FUN($BUF, $_, $FMT, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- metavariable-regex:
metavariable: $FMT
# some format string specifiers are not handled
regex: '(".*%l?s.*"|".*%S.*"|[a-zA-Z_][a-zA-Z0-9_]*)'
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# snprintf
- pattern: snprintf
- pattern: vsnprintf
- pattern: swprintf
- pattern: vswprintf
# buffer in 1st arg (other functions)
- patterns:
- pattern: $FUN($BUF, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# get
- pattern: gets
- pattern: fgets
- pattern: getwd
- pattern: getcwd
# stdio
- pattern: fread
# buffer in 2nd arg (buffer to buffer copy functions)
- patterns:
- pattern: $FUN($_, $BUF, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- pattern-not: $FUN("...", $BUF, ...)
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# bcopy
- pattern: bcopy
# buffer in 2nd arg (other functions)
- patterns:
- pattern: $FUN($_, $BUF, ...)
- pattern-inside: |
$_ $BUF[$_];
...
- pattern-not-inside: |
static $_ $BUF[$_];
...
- metavariable-pattern:
metavariable: $FUN
pattern-either:
# read
- pattern: read
- pattern: pread
# recv
- pattern: recv
- pattern: recvfrom
# assignment (too many false positives)
# - patterns:
# - pattern: $BUF[$_] = ...;
# - pattern: $BUF[] = ...;
# - pattern-inside: |
# $_ $BUF[$_];
# ...
# - pattern-not-inside: |
# static $_ $BUF[$_];
# ...