-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Closed
Labels
questionFurther information is requestedFurther information is requested
Description
Is it possible to search for UAF by tracking clones of arguments from the "free" function? For example, in this code:
/**
* @name Use after free
* @kind path-problem
* @id cpp/workshop/use-after-free
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.dataflow.TaintTracking
import Configs::PathGraph
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node arg) {
exists(FunctionCall call |
call.getTarget().hasGlobalOrStdName("free") and
arg.asDefiningArgument() = call.getArgument(0)
)
}
predicate isSink(DataFlow::Node sink) {
exists(Expr e |
sink.asExpr() = e and
dereferenced(e)
)
}
}
module Configs = TaintTracking::Global<Config>;
from Configs::PathNode source, Configs::PathNode sink
where Configs::hasFlowPath(source, sink)
select sink, source, sink,
"Memory is freed here and used here, causing a potential vulnerability.",
source, "freed here", sink, "used here"
Test 1:
#include <stdlib.h>
#include <time.h>
int main() {
char *a = (char *)malloc(sizeof(char)); // Memory allocation
char *b = a;
if (a != NULL) {
free(a); // Free allocated memory
}
*b = 'b'; // Use after free
return 0;
}
Test 2:
#include <stdlib.h>
#include <time.h>
struct char2 {
char *a;
char *b;
};
int main() {
struct char2 *c2_alias;
struct char2 *c2 = (struct char2 *)malloc(sizeof(struct char2));
c2->a = (char *)malloc(sizeof(char)); // Memory allocation
c2_alias = c2;
time_t seconds = time(NULL) % 3;
free(c2->a); // Free memory which was allocated in 'c2->a'
if (seconds >= 0 && seconds <= 2)
*(c2_alias->a) = 'a'; // Use after free
if (seconds >= 3)
*(c2_alias->b) = 'b';
free(c2);
return 0;
}
Or is it necessary to somehow start from where the "malloc" was made?
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested