Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
TODO overview
</p>
</overview>
<recommendation>
<p>
TODO recommendation
</p>
</recommendation>
<example>
<p>
Example of incorrect code. Floating point state was saved at APC_LEVEL but restored at PASSIVE_LEVEL
</p>
<sample language="c"> <![CDATA[
_IRQL_requires_(PASSIVE_LEVEL)
void driver_utility_bad(void)
{
KIRQL oldIRQL;
KeRaiseIrql(APC_LEVEL, &oldIRQL);
// running at APC level
KFLOATING_SAVE FloatBuf;
if (KeSaveFloatingPointState(&FloatBuf))
{
KeLowerIrql(oldIRQL); // lower back to PASSIVE_LEVEL
// ...
KeRestoreFloatingPointState(&FloatBuf);
}
}

}]]>
</sample>
<p>
Correct example
</p>
<sample language="c"> <![CDATA[
_IRQL_requires_(PASSIVE_LEVEL)
void driver_utility_good(void)
{
// running at APC level
KFLOATING_SAVE FloatBuf;
KIRQL oldIRQL;
KeRaiseIrql(APC_LEVEL, &oldIRQL);

if (KeSaveFloatingPointState(&FloatBuf))
{
KeLowerIrql(oldIRQL);
// ...
KeRaiseIrql(APC_LEVEL, &oldIRQL);
KeRestoreFloatingPointState(&FloatBuf);
}
}
}]]>
</sample>
</example>
<semmleNotes>
<p>
TODO notes
</p>
</semmleNotes>
<references>
<li>
<a href="example.com">
Example link
</a>
</li>
</references>
</qhelp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* @id cpp/drivers/irql-float-state-mismatch
* @kind problem
* @name Irql Float State Mismatch
* @description The IRQL where the floating-point state was saved does not match the current IRQL (for this restore operation).
* @platform Desktop
* @feature.area Multiple
* @impact Insecure Coding Practice
* @repro.text The IRQL at which the driver is executing when it restores a floating-point state is different than the IRQL at which it was executing when it saved the floating-point state.
* Because the IRQL at which the driver runs determines how the floating-point state is saved, the driver must be executing at the same IRQL when it calls the functions to save and to restore the floating-point state.
* @owner.email: [email protected]
* @opaqueid CQLD-C28111
* @problem.severity warning
* @precision medium
* @tags correctness
* @scope domainspecific
* @query-version v1
*/

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

module FloatStateFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(FunctionCall fc |
fc.getTarget().getName().matches("KeSaveFloatingPointState") and
source.asIndirectExpr() = fc.getArgument(0)
)
}

predicate isSink(DataFlow::Node sink) {
exists(FunctionCall fc |
fc.getTarget().getName().matches("KeRestoreFloatingPointState") and
sink.asIndirectExpr() = fc.getArgument(0)
)
}
}

module FloatStateFlow = DataFlow::Global<FloatStateFlowConfig>;

from DataFlow::Node source, DataFlow::Node sink, int irqlSink, int irqlSource
where
FloatStateFlow::flow(source, sink) and
irqlSource = getPotentialExitIrqlAtCfn(source.asIndirectExpr()) and
irqlSink = getPotentialExitIrqlAtCfn(sink.asIndirectExpr()) and
irqlSink != irqlSource
select sink.asIndirectExpr(),
"The irql level where the floating-point state was saved (" + irqlSource +
") does not match the irql level for the restore operation (" + irqlSink + ")."
Loading
Loading