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

Add IrqlSetTooHigh, IrqlSetTooLow queries + update IRQL library #88

Merged
merged 66 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
7c51892
Initial work at IRQL-checking
NateD-MSFT Mar 21, 2023
40d0a8c
Significant extra IRQL work.
NateD-MSFT Mar 21, 2023
c7e73e9
Merge branch 'main' into nated-msft/c28124-c28150
NateD-MSFT Aug 17, 2023
a79ab5b
Merge branch 'development' into nated-msft/c28124-c28150
NateD-MSFT Aug 24, 2023
8f96a77
In-progress work
NateD-MSFT Aug 25, 2023
7479c24
More puttering around with IRQL
NateD-MSFT Sep 13, 2023
9d96c89
Update to CodeQL 2.14.4
NateD-MSFT Sep 13, 2023
24dc7df
Merge branch 'nated-msft/codeql-2144-update' into nated-msft/c28124-c…
NateD-MSFT Sep 13, 2023
1cbca7e
Commit more IRQL code. Needs cleanup.
NateD-MSFT Sep 29, 2023
564d095
Some cleanup and minor fixes to entry IRQL evaluation.
NateD-MSFT Sep 29, 2023
6861e39
Replace old Irql high/low checks with new version and update library.
NateD-MSFT Oct 4, 2023
80a70de
Irql.qll cleanup
NateD-MSFT Oct 5, 2023
ebb570d
Get rid of old prototype version of IrqlTooLow
NateD-MSFT Oct 5, 2023
ee4b80c
Update README.md
NateD-MSFT Oct 5, 2023
890e8e6
Merge branch 'nated-msft/codeql-2144-update' into nated-msft/c28124-c…
NateD-MSFT Oct 5, 2023
e1ddb6a
Clean up file names
NateD-MSFT Oct 5, 2023
6dd4a61
Clean up queries.
NateD-MSFT Oct 5, 2023
c9dc15e
Update test script for IRQL queries.
NateD-MSFT Oct 5, 2023
d964175
Update build-codeql.yaml
NateD-MSFT Oct 5, 2023
9aaa8ff
Update ported_driver_ca_checks.qls
NateD-MSFT Oct 5, 2023
5d5adaa
Merge branch 'nated-msft/codeql-2144-update' into nated-msft/c28120-c…
NateD-MSFT Oct 5, 2023
bb06b89
Add IrqlSetTooHigh/IrqlSetTooLow queries.
NateD-MSFT Oct 10, 2023
4842fd4
Bugfix for IrqlTooHigh/IrqlTooLow
NateD-MSFT Oct 10, 2023
d27b6cd
Fix test issues for several IRQL checks.
NateD-MSFT Oct 10, 2023
23ec263
WIP unit tests for IrqlSetTooHigh and IrqlSetTooLow queries
jacob-ronstadt Oct 10, 2023
b8256c9
WIP unit tests for IrqlSetTooHigh and IrqlSetTooLow queries
jacob-ronstadt Oct 10, 2023
ed5d9d5
WIP more tests and comments
jacob-ronstadt Oct 11, 2023
48a157a
bug fixes
jacob-ronstadt Oct 11, 2023
671cd9c
WIP updates to tests
jacob-ronstadt Oct 11, 2023
a042bd8
WIP update tests
jacob-ronstadt Oct 11, 2023
495add6
remove bad tests. Fix run script to run all tests again. run script n…
jacob-ronstadt Oct 11, 2023
a49921c
update tests for IrqlSetTooHigh
jacob-ronstadt Oct 11, 2023
718c480
Merge branch 'nated-msft/c28124-c28150' into jacob-ronstadt/IrqlSet_t…
NateD-MSFT Oct 11, 2023
3208b0b
WIP IrqlSetTooLow tests
jacob-ronstadt Oct 11, 2023
11b8ad4
Merge branch 'jacob-ronstadt/IrqlSet_tests' of https://github.com/mic…
NateD-MSFT Oct 11, 2023
fbbf360
Fix typo in Irql.qll
NateD-MSFT Oct 12, 2023
6aaf6d5
Fix typo in Irql.qll
NateD-MSFT Oct 12, 2023
6ee7ddd
irqlSetTooHigh tests remove calls to KeGetCurrentIRQL as they are not…
jacob-ronstadt Oct 12, 2023
a698823
update IrqlSetTooLow tests
jacob-ronstadt Oct 12, 2023
4250f6f
update tests. line 90 should be a failling test but isnt
jacob-ronstadt Oct 12, 2023
fd9084b
fix IrqlLowerWithFunctionCall1 to call IrqlMinDispatchLowerIrql_fail1
jacob-ronstadt Oct 13, 2023
f0fe56e
Revert"fix IrqlLowerWithFunctionCall1 to call IrqlMinDispatchLowerIrq…
jacob-ronstadt Oct 13, 2023
a35c1c2
fix IrqlLowerWithFunctionCall1 to call IrqlMinDispatchLowerIrql_fail1
jacob-ronstadt Oct 13, 2023
dd23682
Add some interprocedural IRQL analysis + comments
NateD-MSFT Oct 19, 2023
dfae1fb
Add some interprocedural IRQL analysis + comments
NateD-MSFT Oct 19, 2023
4c8be48
Fix typos
NateD-MSFT Oct 19, 2023
b0ad4a4
Restore non-IRQL test results
NateD-MSFT Oct 20, 2023
a8be8d0
Fix bug in driver_snippet.c that stopped compilation.
NateD-MSFT Oct 20, 2023
9e5ae32
Fix bug in IrqlSetTooHigh
NateD-MSFT Oct 20, 2023
ad31f7a
Fix up test results for IRQL queries
NateD-MSFT Oct 20, 2023
d60f7bf
Fix typos
NateD-MSFT Oct 19, 2023
17345f1
Fix bug in IrqlSetTooHigh
NateD-MSFT Oct 20, 2023
7a7dea7
Merge branch 'nated-msft/c28124-c28150' into jacob-ronstadt/IrqlSet_t…
NateD-MSFT Oct 20, 2023
b210ca9
Fix line endings in diffs
NateD-MSFT Oct 20, 2023
0cd51fb
Regressions due to IRQL changes (+1 benign change)
NateD-MSFT Oct 20, 2023
77b764f
Merge branch 'nated-msft/c28124-c28150' into jacob-ronstadt/IrqlSet_t…
NateD-MSFT Oct 20, 2023
5d1f42e
Update src/drivers/general/queries/experimental/IrqlSetTooHigh/driver…
jacob-ronstadt Oct 20, 2023
b43719f
Update src/drivers/general/queries/experimental/IrqlSetTooHigh/driver…
jacob-ronstadt Oct 20, 2023
1d52536
Update src/drivers/general/queries/experimental/IrqlSetTooHigh/driver…
jacob-ronstadt Oct 20, 2023
6f065ac
Update src/drivers/general/queries/experimental/IrqlSetTooHigh/driver…
jacob-ronstadt Oct 20, 2023
be14ce4
Merge pull request #86 from microsoft/jacob-ronstadt/IrqlSet_tests
jacob-ronstadt Oct 20, 2023
079028b
Fix IrqlNotSaved with the new library.
NateD-MSFT Oct 25, 2023
51234e2
Update InitNotUsed with new DataFlow and a fix.
NateD-MSFT Oct 25, 2023
c693c14
Merge branch 'development' into nated-msft/c28124-c28150
NateD-MSFT Oct 25, 2023
47edb0e
Update ported_driver_ca_checks.qls
NateD-MSFT Oct 26, 2023
1772b88
Merge branch 'development' into nated-msft/c28124-c28150
NateD-MSFT Oct 27, 2023
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
104 changes: 42 additions & 62 deletions src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,8 @@

import cpp
import drivers.libraries.Irql
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.dataflow.DataFlow2

/**
* A function that has at least one parameter annotated with "\_IRQL\_save\_".
*/
class IrqlSaveFunction extends Function {
Parameter p;
int irqlIndex;

IrqlSaveFunction() {
p = this.getParameter(irqlIndex) and
p instanceof IrqlSaveParameter
}

int getIrqlIndex() { result = irqlIndex }
}
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.dataflow.new.DataFlow2

/**
* A data-flow configuration describing flow from an
Expand All @@ -55,7 +40,12 @@ class IrqlFlowConfiguration extends DataFlow::Configuration {
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc, FundamentalIrqlSaveFunction fisf |
fc.getTarget() = fisf and
sink.asExpr() = fc.getArgument(fisf.getIrqlIndex())
(
sink.asExpr() =
fc.getArgument(fisf.(IrqlSavesGlobalAnnotatedFunction).getIrqlParameterSlot())
or
sink.asExpr() = fc.getArgument(fisf.(IrqlSavesToParameterFunction).getIrqlParameterSlot())
)
)
}
}
Expand All @@ -65,17 +55,25 @@ class IrqlFlowConfiguration extends DataFlow::Configuration {
* by the Windows OS itself. This is in general in a Windows Kits header. For
* extra clarity and internal use, we also list the exact header files.
*/
class FundamentalIrqlSaveFunction extends IrqlSaveFunction {
class FundamentalIrqlSaveFunction extends IrqlSavesFunction {
FundamentalIrqlSaveFunction() {
this.getFile().getAbsolutePath().matches("%Windows Kits%.h") or
this.getFile()
.getBaseName()
.matches(["wdm.h", "wdfsync.h", "ntifs.h", "ndis.h", "video.h", "wdfinterrupt.h"])
(
this.getFile().getAbsolutePath().matches("%Windows Kits%.h")
or
this.getFile()
.getBaseName()
.matches(["wdm.h", "wdfsync.h", "ntifs.h", "ndis.h", "video.h", "wdfinterrupt.h"])
) and
(
this instanceof IrqlSavesToParameterFunction or
this instanceof IrqlSavesViaReturnFunction or
this instanceof IrqlSavesGlobalAnnotatedFunction
)
}
}

/**
* A simple data flow from any IrqlSaveParameter to another variable.
* A simple data flow from any IrqlSaveParameter.
*/
class IrqlSaveParameterFlowConfiguration extends DataFlow2::Configuration {
IrqlSaveParameterFlowConfiguration() { this = "IrqlSaveParameterFlowConfiguration" }
Expand All @@ -84,7 +82,7 @@ class IrqlSaveParameterFlowConfiguration extends DataFlow2::Configuration {
source.asParameter() instanceof IrqlSaveParameter
}

override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof VariableAccess }
override predicate isSink(DataFlow::Node sink) { sink instanceof DataFlow::Node }
}

/**
Expand All @@ -97,29 +95,15 @@ class IrqlAssignmentFlowConfiguration extends DataFlow::Configuration {

override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof FunctionCall and
source
.asExpr()
.(FunctionCall)
.getTarget()
.getName()
.matches([
"KeRaiseIrqlToDpcLevel", "KfRaiseIrql", "KfAcquireSpinLock",
"KeAcquireSpinLockAtDpcLevel", "KeAcquireSpinLock", "KeAcquireSpinLockRaiseToDpc"
])
source.asExpr().(FunctionCall).getTarget() instanceof FundamentalIrqlSaveFunction and
source.asExpr().(FunctionCall).getTarget() instanceof IrqlSavesViaReturnFunction
}

override predicate isSink(DataFlow::Node sink) {
// Either we're sinking to a direct reference of a parameter, or...
sink.asExpr().(VariableAccess).getTarget() instanceof IrqlSaveParameter
or
// We a dereferenced pointer to the variable.
sink.asPartialDefinition()
.(PointerDereferenceExpr)
.getOperand()
.(AddressOfExpr)
.getOperand()
.(VariableAccess)
.getTarget() instanceof IrqlSaveVariableFlowedTo
exists(Assignment a |
a.getLValue().getAChild*().(VariableAccess).getTarget() instanceof IrqlSaveVariableFlowedTo and
a.getRValue() = sink.asExpr()
)
}
}

Expand All @@ -132,11 +116,14 @@ class IrqlSaveVariableFlowedTo extends Variable {

IrqlSaveVariableFlowedTo() {
exists(
IrqlSaveParameterFlowConfiguration difca, DataFlow::Node parameter, DataFlow::Node access
IrqlSaveParameterFlowConfiguration ispfc, DataFlow::Node parameter, DataFlow::Node assignment
|
access.asExpr().(VariableAccess).getTarget() = this and
(
this.getAnAssignedValue() = assignment.asExpr() or
this = assignment.asParameter()
) and
parameter.asParameter() = isp and
difca.hasFlow(parameter, access)
ispfc.hasFlow(parameter, assignment)
)
or
this = isp
Expand All @@ -150,26 +137,19 @@ where
// Exclude OS functions
not isp.getFunction() instanceof FundamentalIrqlSaveFunction and
/*
* Case one: does the IrqlSaveParameter (or an alias of it) have the IRQL assigned to it
* directly by calling, for example, KeRaiseIrql?
* Case one: does the IrqlSaveParameter (or an alias of it) have the IRQL assigned to it
* directly by calling, for example, KeRaiseIrql?
*/

not exists(
DataFlow::Node node, IrqlSaveVariableFlowedTo isvft, IrqlAssignmentFlowConfiguration difc
DataFlow::Node node, IrqlSaveVariableFlowedTo isvft, IrqlAssignmentFlowConfiguration iafc
|
isvft.getSaveParameter() = isp and
(
node.asExpr().(VariableAccess).getTarget() = isvft
or
node.asPartialDefinition()
.(PointerDereferenceExpr)
.getOperand()
.(AddressOfExpr)
.getOperand()
.(VariableAccess)
.getTarget() = isvft
exists(Assignment a |
a.getLValue().getAChild*().(VariableAccess).getTarget() = isvft and
a.getRValue() = node.asExpr()
) and
difc.hasFlow(_, node)
iafc.hasFlow(_, node)
) and
// Case two: is the IrqlSaveParameter passed into an OS function that will save a value to it?
not exists(DataFlow::Node node, IrqlFlowConfiguration ifc |
Expand Down
171 changes: 106 additions & 65 deletions src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,23 @@
"driver" : {
"name" : "CodeQL",
"organization" : "GitHub",
"semanticVersion" : "2.11.5",
"semanticVersion" : "2.14.4",
"notifications" : [ {
"id" : "cpp/baseline/expected-extracted-files",
"name" : "cpp/baseline/expected-extracted-files",
"shortDescription" : {
"text" : "Expected extracted files"
},
"fullDescription" : {
"text" : "Files appearing in the source archive that are expected to be extracted."
},
"defaultConfiguration" : {
"enabled" : true
},
"properties" : {
"tags" : [ "expected-extracted-files", "telemetry" ]
}
} ],
"rules" : [ {
"id" : "cpp/drivers/irql-not-saved",
"name" : "cpp/drivers/irql-not-saved",
Expand Down Expand Up @@ -42,7 +58,7 @@
},
"extensions" : [ {
"name" : "microsoft/windows-drivers",
"semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4",
"semanticVersion" : "0.2.0+be14ce4fcaa9006e7636d8605fc53ea7c422a561",
"locations" : [ {
"uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/",
"description" : {
Expand All @@ -54,28 +70,99 @@
"text" : "The QL pack definition file."
}
} ]
} ]
},
"invocations" : [ {
"toolExecutionNotifications" : [ {
"locations" : [ {
"physicalLocation" : {
"artifactLocation" : {
"uri" : "driver/fail_driver1.c",
"uriBaseId" : "%SRCROOT%",
"index" : 1
}
}
} ],
"message" : {
"text" : ""
},
"level" : "none",
"descriptor" : {
"id" : "cpp/baseline/expected-extracted-files",
"index" : 0
},
"properties" : {
"formattedMessage" : {
"text" : ""
}
}
}, {
"name" : "legacy-upgrades",
"semanticVersion" : "0.0.0",
"locations" : [ {
"uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/",
"description" : {
"text" : "The QL pack root directory."
"physicalLocation" : {
"artifactLocation" : {
"uri" : "driver/driver_snippet.c",
"uriBaseId" : "%SRCROOT%",
"index" : 0
}
}
}, {
"uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml",
"description" : {
"text" : "The QL pack definition file."
} ],
"message" : {
"text" : ""
},
"level" : "none",
"descriptor" : {
"id" : "cpp/baseline/expected-extracted-files",
"index" : 0
},
"properties" : {
"formattedMessage" : {
"text" : ""
}
} ]
} ]
},
}
}, {
"locations" : [ {
"physicalLocation" : {
"artifactLocation" : {
"uri" : "driver/fail_driver1.h",
"uriBaseId" : "%SRCROOT%",
"index" : 2
}
}
} ],
"message" : {
"text" : ""
},
"level" : "none",
"descriptor" : {
"id" : "cpp/baseline/expected-extracted-files",
"index" : 0
},
"properties" : {
"formattedMessage" : {
"text" : ""
}
}
} ],
"executionSuccessful" : true
} ],
"artifacts" : [ {
"location" : {
"uri" : "driver/driver_snippet.c",
"uriBaseId" : "%SRCROOT%",
"index" : 0
}
}, {
"location" : {
"uri" : "driver/fail_driver1.c",
"uriBaseId" : "%SRCROOT%",
"index" : 1
}
}, {
"location" : {
"uri" : "driver/fail_driver1.h",
"uriBaseId" : "%SRCROOT%",
"index" : 2
}
} ],
"results" : [ {
"ruleId" : "cpp/drivers/irql-not-saved",
Expand All @@ -85,7 +172,7 @@
"index" : 0
},
"message" : {
"text" : "The parameter [outIrql](1) is annotated \"_IRQL_saves_\" but never has the IRQL saved to it."
"text" : "The parameter [outIrqlFail](1) is annotated \"_IRQL_saves_\" but never has the IRQL saved to it."
},
"locations" : [ {
"physicalLocation" : {
Expand All @@ -97,12 +184,12 @@
"region" : {
"startLine" : 51,
"startColumn" : 44,
"endColumn" : 51
"endColumn" : 55
}
}
} ],
"partialFingerprints" : {
"primaryLocationLineHash" : "6276e1ac4864af21:1",
"primaryLocationLineHash" : "e054bbd9d7acc717:1",
"primaryLocationStartColumnFingerprint" : "43"
},
"relatedLocations" : [ {
Expand All @@ -116,57 +203,11 @@
"region" : {
"startLine" : 51,
"startColumn" : 44,
"endColumn" : 51
}
},
"message" : {
"text" : "outIrql"
}
} ]
}, {
"ruleId" : "cpp/drivers/irql-not-saved",
"ruleIndex" : 0,
"rule" : {
"id" : "cpp/drivers/irql-not-saved",
"index" : 0
},
"message" : {
"text" : "The parameter [myLock](1) is annotated \"_IRQL_saves_\" but never has the IRQL saved to it."
},
"locations" : [ {
"physicalLocation" : {
"artifactLocation" : {
"uri" : "driver/driver_snippet.c",
"uriBaseId" : "%SRCROOT%",
"index" : 0
},
"region" : {
"startLine" : 43,
"startColumn" : 48,
"endColumn" : 54
}
}
} ],
"partialFingerprints" : {
"primaryLocationLineHash" : "342705500599b584:1",
"primaryLocationStartColumnFingerprint" : "47"
},
"relatedLocations" : [ {
"id" : 1,
"physicalLocation" : {
"artifactLocation" : {
"uri" : "driver/driver_snippet.c",
"uriBaseId" : "%SRCROOT%",
"index" : 0
},
"region" : {
"startLine" : 43,
"startColumn" : 48,
"endColumn" : 54
"endColumn" : 55
}
},
"message" : {
"text" : "myLock"
"text" : "outIrqlFail"
}
} ]
} ],
Expand Down
Loading
Loading