Add files via upload

This commit is contained in:
ihsinme
2020-12-26 20:43:25 +03:00
committed by GitHub
parent 2bb96369f1
commit cd7c47ea39
3 changed files with 122 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize)
{
buffer = (unsigned char *)realloc(buffer, newSize);
}
// GOOD: this way we will exclude possible memory leak
unsigned char * tmp;
if (currentSize < newSize)
{
tmp = (unsigned char *)realloc(buffer, newSize);
}
if (tmp == NULL)
{
free(buffer);
}
else
buffer = tmp;

View File

@@ -0,0 +1,38 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Memory leak on failed call to realloc.
The expression mem = realloc (mem, size) is potentially dangerous, if the call fails, we will lose the pointer to the memory block.
An unsuccessful call is possible not only when trying to allocate a large amount of memory, but also when the process memory is strongly segmented.</p>
<p>False positives include code in which immediately after calling the realloc function, the pointer is manipulated without first checking for validity.
In this case, an exception will occur in the program and it will terminate.
But from the point of view of safe coding, these places require the attention of developers.
At this stage, false positives are also possible in situations where the exception handling is quite complicated and occurs outside the base block in which memory is redistributed.</p>
</overview>
<recommendation>
<p>We recommend storing the result in a temporary variable and eliminating memory leak.</p>
</recommendation>
<example>
<p>The following example demonstrates an erroneous and corrected use of the realloc function.</p>
<sample src="MemoryLeakOnFailedCallToRealloc.c" />
</example>
<references>
<li>
CERT C++ Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM51-CPP.+Properly+deallocate+dynamically+allocated+resources">MEM51-CPP. Properly deallocate dynamically allocated resources</a>.
</li>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/WIN30-C.+Properly+pair+allocation+and+deallocation+functions">WIN30-C. Properly pair allocation and deallocation functions</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,64 @@
/**
* @name Memory leak on failed call to realloc
* @description The expression mem = realloc (mem, size) is potentially dangerous, if the call fails, we will lose the pointer to the memory block.
* An unsuccessful call is possible not only when trying to allocate a large amount of memory, but also when the process memory is strongly segmented.
* We recommend storing the result in a temporary variable and eliminating memory leak.
* @kind problem
* @id cpp/memory-leak-on-failed-call-to-realloc
* @problem.severity warning
* @precision medium
* @tags security
* external/cwe/cwe-401
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
class ReallocCallLeak extends FunctionCall {
ReallocCallLeak() {
exists(AssignExpr ex, Variable v, VariableAccess va1, VariableAccess va2 |
this.getTarget().hasName("realloc") and
this = ex.getRValue() and
va1 = ex.getLValue() and
va2 = this.getArgument(0) and
va1 = v.getAnAccess() and
va2 = v.getAnAccess()
)
}
predicate isExistsIfWithExitCall() {
exists(IfStmt ifc |
exists(Variable v, DataFlow::Node source, DataFlow::Node sink |
DataFlow::localFlow(source, sink) and
source.asExpr() = this.getArgument(0) and
this.getArgument(0) = v.getAnAccess() and
ifc.getEnclosingFunction() = this.getEnclosingFunction() and
ifc.getLocation().getStartLine() >= this.getArgument(0).getLocation().getStartLine() and
v.getAnAccess() = ifc.getCondition().getAChild*() and
sink.asExpr() = v.getAnAccess()
) and
exists(FunctionCall fc |
fc.getEnclosingFunction() = this.getEnclosingFunction() and
fc.getTarget().hasName("exit") and
(ifc.getThen().getAChild*() = fc or ifc.getElse().getAChild*() = fc)
)
)
}
predicate isExistsAssertWithArgumentCall() {
exists(FunctionCall fc, Variable v, VariableAccess va1, VariableAccess va2 |
fc.getTarget().hasName("assert") and
this.getEnclosingFunction() = fc.getEnclosingFunction() and
fc.getLocation().getStartLine() > this.getArgument(0).getLocation().getEndLine() and
va2 = this.getArgument(0) and
va1 = v.getAnAccess() and
va2 = v.getAnAccess()
)
}
}
from ReallocCallLeak rcl
where
not rcl.isExistsIfWithExitCall() and
not rcl.isExistsAssertWithArgumentCall()
select rcl, "possible loss of original pointer on unsuccessful call realloc"