CPP: Widen TaintedAllocationSize.ql.

This commit is contained in:
Geoffrey White
2019-01-30 15:54:00 +00:00
parent dab1bba25c
commit 8c75e730e4
4 changed files with 29 additions and 17 deletions

View File

@@ -14,15 +14,22 @@
import cpp
import semmle.code.cpp.security.TaintTracking
from Expr source, Expr tainted, BinaryArithmeticOperation oper,
SizeofOperator sizeof, string taintCause
where tainted(source, tainted)
and oper.getAnOperand() = tainted
and oper.getOperator() = "*"
and oper.getAnOperand() = sizeof
and oper != tainted
and sizeof.getValue().toInt() > 1
and isUserInput(source, taintCause)
predicate taintedAllocSize(Expr e, Expr source, string taintCause) {
(
isAllocationExpr(e) or
any(MulExpr me | me.getAChild() instanceof SizeofOperator) = e
) and exists(Expr tainted |
tainted = e.getAChild() and
tainted.getType().getUnspecifiedType() instanceof IntegralType and
isUserInput(source, taintCause) and
tainted(source, tainted)
)
}
from Expr e, Expr source, string taintCause
where
taintedAllocSize(e, source, taintCause)
select
oper, "This allocation size is derived from $@ and might overflow",
e, "This allocation size is derived from $@ and might overflow",
source, "user input (" + taintCause + ")"

View File

@@ -245,9 +245,10 @@ predicate insideFunctionValueMoveTo(Element src, Element dest)
and format.getConversionChar(arg - formattingSend.getTarget().getNumberOfParameters()) = argFormat
and (argFormat = "s" or argFormat = "S" or argFormat = "@"))
// Expressions computed from tainted data are also tainted
or (exists (FunctionCall call | dest = call and isPureFunction(call.getTarget().getName()) |
call.getAnArgument() = src
and forall(Expr arg | arg = call.getAnArgument() | arg = src or predictable(arg))))
or exists(FunctionCall call | dest = call and isPureFunction(call.getTarget().getName()) |
call.getAnArgument() = src and
forall(Expr arg | arg = call.getAnArgument() | arg = src or predictable(arg))
)
or exists(Element a, Element b |
moveToDependingOnSide(a, b) and
if insideValueSource(a) then

View File

@@ -1,2 +1,6 @@
| test.cpp:42:31:42:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:48:25:48:30 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:49:17:49:30 | new[] | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
| test.cpp:55:11:55:24 | new[] | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |

View File

@@ -39,20 +39,20 @@ int main(int argc, char **argv) {
int tainted = atoi(argv[1]);
MyStruct *arr1 = (MyStruct *)malloc(sizeof(MyStruct)); // GOOD
MyStruct *arr2 = (MyStruct *)malloc(tainted); // BAD [NOT DETECTED]
MyStruct *arr2 = (MyStruct *)malloc(tainted); // BAD
MyStruct *arr3 = (MyStruct *)malloc(tainted * sizeof(MyStruct)); // BAD
MyStruct *arr4 = (MyStruct *)malloc(getTainted() * sizeof(MyStruct)); // BAD [NOT DETECTED]
MyStruct *arr5 = (MyStruct *)malloc(sizeof(MyStruct) + tainted); // BAD [NOT DETECTED]
int size = tainted * 8;
char *chars1 = (char *)malloc(size); // BAD [NOT DETECTED]
char *chars2 = new char[size]; // BAD [NOT DETECTED]
char *chars1 = (char *)malloc(size); // BAD
char *chars2 = new char[size]; // BA
char *chars3 = new char[8]; // GOOD
arr1 = (MyStruct *)realloc(arr1, sizeof(MyStruct) * tainted); // BAD
size = 8;
chars3 = new char[size]; // GOOD
chars3 = new char[size]; // GOOD [FALSE POSITIVE]
return 0;
}