github / codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
https://codeql.github.com
MIT License
7.51k stars 1.49k forks source link

Use-After-Query.ql does not work on this simple situation #16542

Open zouyi73 opened 3 months ago

zouyi73 commented 3 months ago

I use Use-After-Query.ql to detec a simple c code which exists UAF bug , but it doesn't works

/**
 * @name Potential use after free
 * @description An allocated memory block is used after it has been freed. Behavior in such cases is undefined and can cause memory corruption.
 * @kind path-problem
 * @precision high
 * @id cpp/use-after-free
 * @problem.severity warning
 * @security-severity 9.3
 * @tags reliability
 *       security
 *       external/cwe/cwe-416
 */

import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.ir.IR
import semmle.code.cpp.security.flowafterfree.FlowAfterFree
import semmle.code.cpp.security.flowafterfree.UseAfterFree
import UseAfterFreeTrace::PathGraph

module UseAfterFreeParam implements FlowFromFreeParamSig {
  predicate isSink = isUse/2;

  predicate isExcluded = isExcludedMmFreePageFromMdl/2;

  predicate sourceSinkIsRelated = defaultSourceSinkIsRelated/2;
}

import UseAfterFreeParam

module UseAfterFreeTrace = FlowFromFree<UseAfterFreeParam>;

from UseAfterFreeTrace::PathNode source, UseAfterFreeTrace::PathNode sink, DeallocationExpr dealloc
where
  UseAfterFreeTrace::flowPath(source, sink) and
  isFree(source.getNode(), _, _, dealloc)
select sink.getNode(), source, sink, "Memory may have been previously freed by $@.", dealloc,
  dealloc.toString()

void process_buffer(char *buffer) { if (buffer != NULL) { printf("Processing buffer: %s\n", buffer); } }

void free_buffer(char *buffer) { if (buffer != NULL) { free(buffer); // 释放内存 printf("Buffer freed.\n"); } }

void use_after_free(char *buffer) { // 释放后再次使用内存,存在UAF漏洞 process_buffer(buffer); }

int main() { char buffer = (char )malloc(100); // 分配100字节的内存 if (buffer == NULL) { perror("Failed to allocate memory"); exit(EXIT_FAILURE); }

strcpy(buffer, "This is a test string."); // 使用分配的内存
printf("Buffer before free: %s\n", buffer);

free_buffer(buffer); // 调用函数释放内存

use_after_free(buffer); // 释放后再次使用

return 0;

}


its result shows there has no bugs, I don't know why
MathiasVP commented 3 months ago

Hi @zouyi73,

The current version of cpp/use-after-free only flags up an alert if the use is unconditional following the deallocation, or if the deallocation unconditionally precedes the use. This is done to reduce the amount of results on the query. Eventually, we'd like to expand the coverage of the query.

zouyi73 commented 3 months ago

Hi @zouyi73,

The current version of cpp/use-after-free only flags up an alert if the use is unconditional following the deallocation, or if the deallocation unconditionally precedes the use. This is done to reduce the amount of results on the query. Eventually, we'd like to expand the coverage of the query.

@MathiasVP Thanks for your reply! Do you mean (if buffer != NULL) will influence codeql analysis? But when I remove (if buffer != NULL) , the cpp/use-after-free can not detect the UAF bug immediately(it indeed costs so long time that I cancel its analysis)。I don't know if cross-function call could influece because I write use and free in a function it can detect the bug. Could you explain this? Thank you so much!