Skip to content

[C] Taint propagation and isSanitizer() - interproc and ptr #131

Answered
81d ago
· 1 reply
Copy link
81d

@vaioco vaioco

Hi *,
I am struggling with a TaintTracking query using the isSanitizer() to detect when a tainted data is used in a comparison operation.
I have the following code:

void get_check_data( int* p ) {
    copy_from_user(p, src, len);
    if(*p < 0 ) *p = 0; // I want to cover this scenario
}

void f1(){
    int* p;
    copy_from_user(p, src, len);
    if( *p < 0 ) *p = 0;
    mysink(*p);
}

void f2(){
    int p;
    get_check_data(&p);
    mysink(p);
}

void main(){
    f1();
    f2();
}

I wrote the query to find the flow from source (copy_from_user) to sink (mysink) and it works. Actually I am struggling with the isSanitizer() because I want to filter out those expressions where a tainted node is used in a comparison op, I managed to achieve it for f1() but not for f2()
The query looks like the following:

class CopyFromUserSource extends DataFlow::Node { 
    CopyFromUserSource() {
        exists(FunctionCall fc|
            fc.getTarget().getName() = "copy_from_user"
            and this.asDefiningArgument() = fc.getArgument(0)
        )
    }
} 
// this is called in isSanitizer()
// a tainted node guarded by a lte condition
predicate isASanitizer(Data::Flow node){
    exists( IfStmt aif, LTExpr lte|
        node.asExpr().(PointerDereferenceExpr).getOperand().(VariableAccess).getTarget().getAnAccess() = aif.getControllingExpr().getAChild*()
        and aif.getASuccessor+() = node.asExpr()
        and not ( node.asExpr() = aif.getControllingExpr().getAChild*() )
        and lte = aif.getControllingExpr().getAChild*().(RelationalOperation)
    )    
    or exists( IfStmt aif, LTExpr lte|
        node.asExpr().(VariableAccess).getTarget().getAnAccess() = aif.getControllingExpr().getAChild*()
        and aif.getASuccessor+() = node.asExpr()
        and not ( node.asExpr() = aif.getControllingExpr().getAChild*() )
        and lte = aif.getControllingExpr().getAChild*().(RelationalOperation)
    )
}

however, this version is not working for f2().
I used hasPartialFlow() to debug tainting propagation and I noticed that seems the taint does not reach to expression if(*p < 0 ) *p = 0; in get_check_data().
To my understanding, that expression should be a tainted node because it is an access to tainted data. is that correct? what am I missing?

thanks

ps: thanks for bringing us codeQL

Replies

Answer selected by vaioco

@rdmarsh2 rdmarsh2
Collaborator

That's a known issue with semmle.code.cpp.dataflow.TaintTracking. We're in the process of switching to a new version with the same interface in semmle.code.cpp.ir.dataflow.TaintTracking that handles interprocedural flow through pointers, but we haven't fully replaced the old version yet. You should be able to change your import to use the new version without changing any other code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants
Beta
You can’t perform that action at this time.