Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Silence alerts coming from CMake test compilation files #18408

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2025-01-07-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: feature
---
* A new abstract class `ConfigurationTestFile` (`semmle.code.cpp.ConfigurationTestFile.ConfigurationTestFile`) was introduced, which represents files created to test the build configuration. A subclass `CmakeTryCompileFile` of `ConfigurationTestFile` was also introduced, which represents files created by CMake to test the build configuration.
28 changes: 28 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/ConfigurationTestFile.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Provides classes for identifying files that created to test the
* build configuration. It is often desirable to exclude these files
* from analysis.
*/

import File

/**
* A file created to test the system configuration.
*/
abstract class ConfigurationTestFile extends File { }

/**
* A file created by CMake to test the system configuration.
*/
class CmakeTryCompileFile extends ConfigurationTestFile {
CmakeTryCompileFile() {
exists(Folder folder, Folder parent |
folder = this.getParentContainer() and
parent = folder.getParentContainer()
|
folder.getBaseName().matches("TryCompile-%") and
parent.getBaseName() = "CMakeScratch" and
parent.getParentContainer().getBaseName() = "CMakeFiles"
)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to worry about files in subdirectories of the TryCompile-* directory? i.e. CMakeFiles/CMAkeScratch/TryCompile-foo/bar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. My understanding is that CMake creates each directory on-the-fly and only uses it for one test compilation.

4 changes: 3 additions & 1 deletion cpp/ql/src/Best Practices/SloppyGlobal.ql
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
*/

import cpp
import semmle.code.cpp.ConfigurationTestFile

from GlobalVariable gv
where
gv.getName().length() <= 3 and
not gv.isStatic()
not gv.isStatic() and
not gv.getFile() instanceof ConfigurationTestFile // variables in files generated during configuration are likely false positives
select gv,
"Poor global variable name '" + gv.getName() +
"'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo)."
10 changes: 7 additions & 3 deletions cpp/ql/src/Critical/OverflowStatic.ql
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import cpp
import semmle.code.cpp.commons.Buffer
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.ConfigurationTestFile
import LoopBounds

private predicate staticBufferBase(VariableAccess access, Variable v) {
Expand Down Expand Up @@ -148,7 +149,10 @@ predicate outOfBounds(BufferAccess bufaccess, string msg) {

from Element error, string msg
where
overflowOffsetInLoop(error, msg) or
wrongBufferSize(error, msg) or
outOfBounds(error, msg)
(
overflowOffsetInLoop(error, msg) or
wrongBufferSize(error, msg) or
outOfBounds(error, msg)
) and
not error.getFile() instanceof ConfigurationTestFile // elements in files generated during configuration are likely false positives
select error, msg
4 changes: 3 additions & 1 deletion cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

import cpp
import semmle.code.cpp.ConfigurationTestFile

from EqualityOperation ro, Expr left, Expr right
where
Expand All @@ -20,5 +21,6 @@ where
ro.getAnOperand().getExplicitlyConverted().getType().getUnderlyingType() instanceof
FloatingPointType and
not ro.getAnOperand().isConstant() and // comparisons to constants generate too many false positives
not left.(VariableAccess).getTarget() = right.(VariableAccess).getTarget() // skip self comparison
not left.(VariableAccess).getTarget() = right.(VariableAccess).getTarget() and // skip self comparison
not ro.getFile() instanceof ConfigurationTestFile // expressions in files generated during configuration are likely false positives
select ro, "Equality checks on floating point values can yield unexpected results."
4 changes: 3 additions & 1 deletion cpp/ql/src/Likely Bugs/Likely Typos/ExprHasNoEffect.ql
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
*/

import cpp
private import semmle.code.cpp.commons.Exclusions
import semmle.code.cpp.commons.Exclusions
import semmle.code.cpp.ConfigurationTestFile

class PureExprInVoidContext extends ExprInVoidContext {
PureExprInVoidContext() { this.isPure() }
Expand Down Expand Up @@ -90,6 +91,7 @@ where
not peivc.getType() instanceof UnknownType and
not functionContainsDisabledCodeRecursive(peivc.(FunctionCall).getTarget()) and
not functionDefinedInIfDefRecursive(peivc.(FunctionCall).getTarget()) and
not peivc.getFile() instanceof ConfigurationTestFile and // expressions in files generated during configuration are likely false positives
if peivc instanceof FunctionCall
then
exists(Function target |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@

import cpp
import TooFewArguments
import semmle.code.cpp.ConfigurationTestFile

from FunctionCall fc, Function f
where tooFewArguments(fc, f)
where
tooFewArguments(fc, f) and
not fc.getFile() instanceof ConfigurationTestFile // calls in files generated during configuration are likely false positives
select fc, "This call has fewer arguments than required by $@.", f, f.toString()
4 changes: 3 additions & 1 deletion cpp/ql/src/Security/CWE/CWE-120/BadlyBoundedWrite.ql
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.ConfigurationTestFile

/*
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
Expand All @@ -26,7 +27,8 @@ where
bw.hasExplicitLimit() and // has an explicit size limit
destSize = max(getBufferSize(bw.getDest(), _)) and
bw.getExplicitLimit() > destSize and // but it's larger than the destination
not bw.getDest().getType().stripType() instanceof ErroneousType // destSize may be incorrect
not bw.getDest().getType().stripType() instanceof ErroneousType and // destSize may be incorrect
not bw.getFile() instanceof ConfigurationTestFile // expressions in files generated during configuration are likely false positives
select bw,
"This '" + bw.getBWDesc() + "' operation is limited to " + bw.getExplicitLimit() +
" bytes but the destination is only " + destSize + " bytes."
2 changes: 2 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-732/DoNotCreateWorldWritable.ql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import cpp
import FilePermissions
import semmle.code.cpp.ConfigurationTestFile

predicate worldWritableCreation(FileCreationExpr fc, int mode) {
mode = localUmask(fc).mask(fc.getMode()) and
Expand All @@ -27,6 +28,7 @@ predicate setWorldWritable(FunctionCall fc, int mode) {
from Expr fc, int mode, string message
where
worldWritableCreation(fc, mode) and
not fc.getFile() instanceof ConfigurationTestFile and // expressions in files generated during configuration are likely false positives
message =
"A file may be created here with mode " + octalFileMode(mode) +
", which would make it world-writable."
Expand Down
4 changes: 4 additions & 0 deletions cpp/ql/src/change-notes/2025-01-07-cmake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `cpp/badly-bounded-write`, `cpp/equality-on-floats`, `cpp/short-global-name`, `cpp/static-buffer-overflow`, `cpp/too-few-arguments`, `cpp/useless-expression`, `cpp/world-writable-file-creation` queries no longer produce alerts on files created by CMake to test the build configuration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
typedef long long size_t;

size_t strlen(const char *s);

int main() {
strlen("");
geoffw0 marked this conversation as resolved.
Show resolved Hide resolved
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Likely Bugs/Likely Typos/ExprHasNoEffect.ql
Loading