-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Closed
Labels
Description
I want to search pattern like this
struct _wStream
{
char *buffer;
char *pointer;
size_t length;
size_t capacity;
size_t count;
};
typedef struct _wStream wStream;
#define _stream_read_n32_le(_t, _s, _v, _p) \
do \
{ \
(_v) = (_t)(*(_s)->pointer) + (((_t)(*((_s)->pointer + 1))) << 8) + \
(((_t)(*((_s)->pointer + 2))) << 16) + (((_t)(*((_s)->pointer + 3))) << 24); \
if (_p) \
Stream_Seek(_s, sizeof(_t)); \
} while (0)
#define Stream_Read_UINT32(_s, _v) _stream_read_n32_le(UINT32, _s, _v, TRUE)
int realloc_test(wStream *s)
{
unsigned int count;
unsigned int x1, x2;
char *pp = malloc(20);
Stream_Read_UINT32(s, x1);
count += x1;
Stream_Read_UINT32(s, x2);
count += x2;
char *p = realloc(pp, count);
if (p == NULL)
{
free(pp);
return 1;
}
return 0;
}
I try write the following query , but I have no result
import cpp
import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.dataflow.DataFlow
class PointerAccess extends FieldAccess {
PointerAccess() {
this.getTarget().getQualifiedName().matches("%wStream%") and
this.getTarget().hasName("pointer")
}
}
class ReadSteam extends AssignExpr {
ReadSteam() {
exists(PointerDereferenceExpr pde |
pde.getOperand() instanceof PointerAccess and
this.getAnOperand() = pde
)
}
}
class Target extends Expr {
Target() {
this =
any(MacroInvocation mi | mi.getOutermostMacroAccess().getMacroName().matches("Stream_Read_%"))
.getExpr()
}
}
class ReadStreamConfiguration extends TaintTracking::Configuration {
ReadStreamConfiguration() { this = "ReadStreamConfiguration" }
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof Target }
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc |
fc.getTarget().getName().regexpMatch("memcpy|memmove") and
fc.getArgument(2) = sink.asExpr()
)
or
exists(FunctionCall fc |
fc.getTarget().hasName("realloc") and
fc.getArgument(1) = sink.asExpr()
)
// and
// not exists(IfStmt ifs | ifs.getControllingExpr() = sink.asExpr())
}
}
// from ReadStreamConfiguration cfg, Expr sizeArg, Expr e
// where cfg.hasFlow(DataFlow::exprNode(e), DataFlow::exprNode(sizeArg))
// select e, sizeArg
from Target rs, FunctionCall fc
where
fc.getTarget().hasName("realloc") and
exists(DataFlow::Node source, DataFlow::Node sink |
DataFlow::localFlow(source, sink) and
source.asExpr() instanceof ReadSteam and
sink.asExpr() = fc.getArgument(1)
)
select rs, fc, fc.getArgument(1)
anything worry?
Taint data is in stream->pointer
, I want to track data from pointer
to the size
argument of realloc
.