diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp new file mode 100644 index 00000000..4889a48b --- /dev/null +++ b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp @@ -0,0 +1,52 @@ + + + +

+ TODO overview +

+
+ +

+ TODO recommendation +

+
+ +

+ Function annotated with _IRQL_requires_same_ but can possibly exit at a different IRQL level. +

+ + +

+ TODO example 2 +

+ + +
+ +

+ TODO notes +

+
+ +
  • + + Example link + +
  • +
    +
    diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql new file mode 100644 index 00000000..3e521efa --- /dev/null +++ b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/irql-inconsistent-with-required + * @kind problem + * @name Irql Inconsistent With Required + * @description The actual IRQL is inconsistent with the required IRQL + * @platform Desktop + * @feature.area Multiple + * @impact Insecure Coding Practice + * @repro.textAn _IRQL_requires_same_ annotation specifies that the driver should be executing at a particular IRQL when the function completes, but there is at least one path in which the driver is executing at a different IRQL when the function completes. + * @owner.email: sdat@microsoft.com + * @opaqueid CQLD-C28156 + * @problem.severity warning + * @precision medium + * @tags correctness + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.libraries.Irql + +from + IrqlRequiresSameAnnotatedFunction f, int irqlLevelEntry, int irqlLevelExit, + ControlFlowNode exitCfn, ControlFlowNode entryCfn +where + exitCfn = f.getControlFlowScope() and + entryCfn = f.getBlock() and + irqlLevelEntry = getPotentialExitIrqlAtCfn(entryCfn) and + irqlLevelExit = getPotentialExitIrqlAtCfn(exitCfn) and + irqlLevelEntry != irqlLevelExit +select f, + "Possible IRQL level at function completion inconsistent with the required IRQL level for some path. Irql level expected: " + + irqlLevelEntry + ". Irql level found: " + irqlLevelExit + + ". Review the IRQL level of the function." \ No newline at end of file diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif new file mode 100644 index 00000000..ccee3d2c --- /dev/null +++ b/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif @@ -0,0 +1,312 @@ +{ + "$schema": "https://json.schemastore.org/sarif-2.1.0.json", + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "CodeQL", + "organization": "GitHub", + "semanticVersion": "2.19.3", + "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" + ] + } + }, + { + "id": "cpp/extractor/summary", + "name": "cpp/extractor/summary", + "shortDescription": { + "text": "C++ extractor telemetry" + }, + "fullDescription": { + "text": "C++ extractor telemetry" + }, + "defaultConfiguration": { + "enabled": true + } + } + ], + "rules": [ + { + "id": "cpp/drivers/irql-inconsistent-with-required", + "name": "cpp/drivers/irql-inconsistent-with-required", + "shortDescription": { + "text": "Irql Inconsistent With Required" + }, + "fullDescription": { + "text": "The actual IRQL is inconsistent with the required IRQL" + }, + "defaultConfiguration": { + "enabled": true, + "level": "warning" + }, + "properties": { + "tags": [ + "correctness" + ], + "description": "The actual IRQL is inconsistent with the required IRQL", + "feature.area": "Multiple", + "id": "cpp/drivers/irql-inconsistent-with-required", + "impact": "Insecure Coding Practice", + "kind": "problem", + "name": "Irql Inconsistent With Required", + "opaqueid": "CQLD-C28156", + "owner.email:": "sdat@microsoft.com", + "platform": "Desktop", + "precision": "medium", + "problem.severity": "warning", + "query-version": "v1", + "repro.textAn": "_IRQL_requires_same_ annotation specifies that the driver should be executing at a particular IRQL when the function completes, but there is at least one path in which the driver is executing at a different IRQL when the function completes.", + "scope": "domainspecific" + } + } + ] + }, + "extensions": [ + { + "name": "microsoft/windows-drivers", + "semanticVersion": "1.3.0+2a7c167ba9555b452f626258191b4709647a936f", + "locations": [ + { + "uri": "file:///C:/codeql-home/WDDST/src/", + "description": { + "text": "The QL pack root directory." + }, + "properties": { + "tags": [ + "CodeQL/LocalPackRoot" + ] + } + }, + { + "uri": "file:///C:/codeql-home/WDDST/src/qlpack.yml", + "description": { + "text": "The QL pack definition file." + }, + "properties": { + "tags": [ + "CodeQL/LocalPackDefinitionFile" + ] + } + } + ] + }, + { + "name": "codeql/cpp-all", + "semanticVersion": "3.1.0+d42788844f7ec0a6b9832140313cc2318e513987", + "locations": [ + { + "uri": "file:///C:/Users/jronstadt/.codeql/packages/codeql/cpp-all/3.1.0/", + "description": { + "text": "The QL pack root directory." + }, + "properties": { + "tags": [ + "CodeQL/LocalPackRoot" + ] + } + }, + { + "uri": "file:///C:/Users/jronstadt/.codeql/packages/codeql/cpp-all/3.1.0/qlpack.yml", + "description": { + "text": "The QL pack definition file." + }, + "properties": { + "tags": [ + "CodeQL/LocalPackDefinitionFile" + ] + } + } + ] + } + ] + }, + "invocations": [ + { + "toolExecutionNotifications": [ + { + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "driver/driver_snippet.c", + "uriBaseId": "%SRCROOT%", + "index": 0 + } + } + } + ], + "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": 1 + } + } + } + ], + "message": { + "text": "" + }, + "level": "none", + "descriptor": { + "id": "cpp/baseline/expected-extracted-files", + "index": 0 + }, + "properties": { + "formattedMessage": { + "text": "" + } + } + }, + { + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "driver/fail_driver1.c", + "uriBaseId": "%SRCROOT%", + "index": 2 + } + } + } + ], + "message": { + "text": "" + }, + "level": "none", + "descriptor": { + "id": "cpp/baseline/expected-extracted-files", + "index": 0 + }, + "properties": { + "formattedMessage": { + "text": "" + } + } + }, + { + "message": { + "text": "Internal telemetry for the C++ extractor.\n\nNo action needed.", + "markdown": "Internal telemetry for the C++ extractor.\n\nNo action needed." + }, + "level": "note", + "timeUtc": "2025-01-16T00:50:38.920418700Z", + "descriptor": { + "id": "cpp/extractor/summary", + "index": 1 + }, + "properties": { + "attributes": { + "cache-hits": 0, + "cache-misses": 1, + "extractor-failures": 1, + "extractor-successes": 0, + "trap-caching": "disabled" + }, + "visibility": { + "statusPage": false, + "telemetry": true + } + } + } + ], + "executionSuccessful": true + } + ], + "artifacts": [ + { + "location": { + "uri": "driver/driver_snippet.c", + "uriBaseId": "%SRCROOT%", + "index": 0 + } + }, + { + "location": { + "uri": "driver/fail_driver1.h", + "uriBaseId": "%SRCROOT%", + "index": 1 + } + }, + { + "location": { + "uri": "driver/fail_driver1.c", + "uriBaseId": "%SRCROOT%", + "index": 2 + } + } + ], + "results": [ + { + "ruleId": "cpp/drivers/irql-inconsistent-with-required", + "ruleIndex": 0, + "rule": { + "id": "cpp/drivers/irql-inconsistent-with-required", + "index": 0 + }, + "message": { + "text": "Possible IRQL level at function completion inconsistent with the required IRQL level for some path. Irql level expected: 0. Irql level found: 2. Review the IRQL level of the function." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "driver/driver_snippet.c", + "uriBaseId": "%SRCROOT%", + "index": 0 + }, + "region": { + "startLine": 11, + "startColumn": 27, + "endColumn": 32 + } + } + } + ], + "partialFingerprints": { + "primaryLocationLineHash": "e8222ed04cfffe33:1", + "primaryLocationStartColumnFingerprint": "26" + } + } + ], + "columnKind": "utf16CodeUnits", + "properties": { + "semmle.formatSpecifier": "sarifv2.1.0" + } + } + ] +} \ No newline at end of file diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c b/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c new file mode 100644 index 00000000..163e7b99 --- /dev/null +++ b/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Macros to enable or disable a code section that may or maynot conflict with this test. +#define SET_DISPATCH 1 + +void top_level_call() +{ +} + +_IRQL_requires_same_ void fail1(PKIRQL oldIrql) +{ + + if (oldIrql == PASSIVE_LEVEL) + { + KeLowerIrql(*oldIrql); + } + else + { + KeRaiseIrql(DISPATCH_LEVEL, oldIrql); // Function exits at DISPATCH_LEVEL + } +} + +_IRQL_requires_same_ + NTSTATUS + pass1(PKIRQL oldIrql) +{ + KeRaiseIrql(DISPATCH_LEVEL, oldIrql); + KeLowerIrql(*oldIrql); + return STATUS_SUCCESS; +} \ No newline at end of file