mirror of
https://github.com/github/codeql.git
synced 2025-12-29 15:16:34 +01:00
53 lines
1.8 KiB
Plaintext
53 lines
1.8 KiB
Plaintext
/**
|
|
* @name Copy function using source size
|
|
* @description Calling a copy operation with a size derived from the source
|
|
* buffer instead of the destination buffer may result in a buffer overflow.
|
|
* @kind problem
|
|
* @id cpp/overflow-destination
|
|
* @problem.severity warning
|
|
* @precision low
|
|
* @tags reliability
|
|
* security
|
|
* external/cwe/cwe-119
|
|
* external/cwe/cwe-131
|
|
*/
|
|
|
|
import cpp
|
|
import semmle.code.cpp.security.TaintTracking
|
|
|
|
/**
|
|
* Holds if `fc` is a call to a copy operation where the size argument contains
|
|
* a reference to the source argument. For example:
|
|
* ```
|
|
* memcpy(dest, src, sizeof(src));
|
|
* ```
|
|
*/
|
|
predicate sourceSized(FunctionCall fc, Expr src) {
|
|
fc.getTarget().hasGlobalOrStdName(["strncpy", "strncat", "memcpy", "memmove"]) and
|
|
exists(Expr dest, Expr size, Variable v |
|
|
fc.getArgument(0) = dest and
|
|
fc.getArgument(1) = src and
|
|
fc.getArgument(2) = size and
|
|
src = v.getAnAccess() and
|
|
size.getAChild+() = v.getAnAccess() and
|
|
// exception: `dest` is also referenced in the size argument
|
|
not exists(Variable other |
|
|
dest = other.getAnAccess() and size.getAChild+() = other.getAnAccess()
|
|
) and
|
|
// exception: `src` and `dest` are both arrays of the same type and size
|
|
not exists(ArrayType srctype, ArrayType desttype |
|
|
dest.getType().getUnderlyingType() = desttype and
|
|
src.getType().getUnderlyingType() = srctype and
|
|
desttype.getBaseType().getUnderlyingType() = srctype.getBaseType().getUnderlyingType() and
|
|
desttype.getArraySize() = srctype.getArraySize()
|
|
)
|
|
)
|
|
}
|
|
|
|
from FunctionCall fc, Expr vuln, Expr taintSource
|
|
where
|
|
sourceSized(fc, vuln) and
|
|
tainted(taintSource, vuln)
|
|
select fc,
|
|
"To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size."
|