Closed as not planned
Closed as not planned
Description
Take the following two examples:
static File safe11() throws IOException {
File temp = null;
if (temp == null) {
while (true) {
temp = File.createTempFile("test", "directory");
if (temp.delete() && temp.mkdir()) {
break;
}
}
}
return temp;
}
File safe12temp;
File safe12() throws IOException {
if (safe12temp == null) {
while (true) {
safe12temp = File.createTempFile("test", "directory");
if (safe12temp.delete() && safe12temp.mkdir()) {
break;
}
}
}
return safe12temp;
}
Let's take File.createTempFile
as a source of taint, and _.mkdir()
is a guard.
/**
* All methods on the class `java.io.File` that create directories.
*/
class MethodFileCreatesDirs extends Method {
MethodFileCreatesDirs() {
getDeclaringType() instanceof TypeFile and
hasName(["mkdir", "mkdirs"])
}
}
/**
* An expression that will create a directory without throwing an exception if a file/directory already exists.
*/
private predicate isNonThrowingDirectoryCreationExpression(Expr expr, MethodAccess creationCall) {
creationCall.getMethod() instanceof MethodFileCreatesDirs and creationCall.getQualifier() = expr
}
private class DirectoryCreationBarrierGuard extends DataFlow::BarrierGuard {
DirectoryCreationBarrierGuard() { isNonThrowingDirectoryCreationExpression(_, this) }
override predicate checks(Expr e, boolean branch) {
this.controls(e, branch)
}
}
Running a query for DirectoryCreationBarrierGuard
will find the safe12temp.mkdir()
and temp.mkdir()
.
However, when quick evaluating the DirectoryCreationBarrierGuard::checks
method, it will not find that safe12temp.mkdir()
is a check for return safe12temp
and temp.mkdir()
is a check for return safe12temp;
.
Interesting note: as soon as the outer null
check is removed, codeQL does correctly identify the guard controls the return. For example, this is detected as correctly guarded:
File safe12temp;
File safe12() throws IOException {
while (true) {
safe12temp = File.createTempFile("test", "directory");
if (safe12temp.delete() && safe12temp.mkdir()) {
break;
}
}
return safe12temp;
}
Practical example:
The above code is flagged as a false positive result when executing this new query: #4473