-
Notifications
You must be signed in to change notification settings - Fork 1.9k
C++: Model taint flow through pointer-returning methods using MaD summaries #21623
Copy link
Copy link
Open
Labels
questionFurther information is requestedFurther information is requested
Description
Hi, i am trying to use MaD summary rules to model taint tracking through a protobuf-style API pattern where a container method returns a pointer to an internal element, and taint is written through that pointer.
c++ code(simplified protobuf-like pattern):
#include <iostream>
#include <string>
class Person {
public:
void set_name(const std::string& name) { name_ = name; }
const std::string& name() const { return name_; }
std::string DebugString() const {
return "Person { name: \"" + name_ + "\" }";
}
private:
std::string name_;
};
class AddressBook {
public:
AddressBook() : count_(0) {}
Person* add_people() {
people_[count_] = new Person();
return people_[count_++];
}
std::string DebugString() const {
std::string result = "AddressBook { ";
for (int i = 0; i < count_; i++) {
result += people_[i]->DebugString() + " ";
}
result += "}";
return result;
}
~AddressBook() {
for (int i = 0; i < count_; i++) delete people_[i];
}
private:
Person* people_[10];
int count_;
};
std::string source_func() {
return "source";
}
void sink_func(const AddressBook& book) {
std::cout << book.DebugString() << std::endl;
}
int main() {
std::string name = source_func();
AddressBook address_book;
Person* person1 = address_book.add_people();
person1->set_name(name);
sink_func(address_book);
return 0;
}
query:
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import Flow::PathGraph
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
exists(FunctionCall call |
call.getTarget().hasName("source_func") and
node.asExpr() = call
)
}
predicate isSink(DataFlow::Node node) {
exists(FunctionCall call |
call.getTarget().hasName("sink_func") and
node.asIndirectExpr() = call.getArgument(0)
)
}
predicate allowImplicitRead(DataFlow::Node n, DataFlow::ContentSet cs) {
isSink(n)
}
}
module Flow = TaintTracking::Global<Config>;
from Flow::PathNode source, Flow::PathNode sink
where Flow::flowPath(source, sink)
select sink.getNode(), source, sink,
"$@ to sink_func argument",
source.getNode(), "source_func()"
MaD:
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data:
- ["", "Person", true, "set_name", "", "", "Argument[*0]", "Argument[-1].Field[name_]", "value", "manual"]
- ["", "AddressBook", true, "add_people", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"]
I need taint to propagate to address_book but my query produces no results, how should i adjust my MaD rules so that address_book is recognized as tainted?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested
Type
Fields
Give feedbackNo fields configured for issues without a type.