Merge branch 'brodes/seh_flow_phase1_throwing_models' into brodes/seh_flow_phase2_splitting_seh_edges

This commit is contained in:
REDMOND\brodes
2024-12-04 13:28:21 -05:00
12 changed files with 43 additions and 102 deletions

View File

@@ -1,4 +1,4 @@
---
category: deprecated
---
* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonThrowing` class from `semmle.code.cpp.models.interfaces.Throwing` instead.
* The `NonThrowing` class (`semmle.code.cpp.models.interfaces.NonThrowing`) has been deprecated. Please use the `NonCppThrowingFunction` class instead.

View File

@@ -364,10 +364,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
final override predicate mayThrowException() {
expr.getTarget().(ThrowingFunction).mayThrowException(_)
or
expr.getTarget() instanceof AlwaysSehThrowingFunction
}
final override predicate mustThrowException() {
expr.getTarget().(ThrowingFunction).mayThrowException(true)
or
expr.getTarget() instanceof AlwaysSehThrowingFunction
}
}

View File

@@ -9,14 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
* `__builtin___memcpy_chk`.
*/
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
AliasFunction, NonThrowingFunction
AliasFunction, NonCppThrowingFunction
{
MemcpyFunction() {
// memcpy(dest, src, num)
@@ -106,8 +106,6 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
index = this.getParamDest()
}
override TCxxException getExceptionType() { any() }
}
private string mempcpy() { result = ["mempcpy", "wmempcpy"] }

View File

@@ -8,10 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction, NonThrowingFunction
SideEffectFunction, NonCppThrowingFunction
{
MemsetFunctionModel() {
this.hasGlobalOrStdOrBslName("memset")
@@ -74,8 +74,6 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
i = 0 and
if this.hasGlobalName(bzero()) then result = 1 else result = 2
}
override TCxxException getExceptionType() { any() }
}
private string bzero() { result = ["bzero", "explicit_bzero"] }

View File

@@ -1,4 +1,4 @@
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* A function that is annotated with a `noexcept` specifier (or the equivalent
@@ -6,8 +6,6 @@ import semmle.code.cpp.models.interfaces.Throwing
*
* Note: The `throw` specifier was deprecated in C++11 and removed in C++17.
*/
class NoexceptFunction extends NonThrowingFunction {
class NoexceptFunction extends NonCppThrowingFunction {
NoexceptFunction() { this.isNoExcept() or this.isNoThrow() }
override TCxxException getExceptionType() { any() }
}

View File

@@ -8,12 +8,12 @@
import semmle.code.cpp.models.interfaces.FormattingFunction
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard functions `printf`, `wprintf` and their glib variants.
*/
private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction {
private class Printf extends FormattingFunction, AliasFunction, NonCppThrowingFunction {
Printf() {
this instanceof TopLevelFunction and
(
@@ -32,14 +32,12 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct
override predicate parameterEscapesOnlyViaReturn(int n) { none() }
override predicate parameterIsAlwaysReturned(int n) { none() }
override TCxxException getExceptionType() { any() }
}
/**
* The standard functions `fprintf`, `fwprintf` and their glib variants.
*/
private class Fprintf extends FormattingFunction, NonThrowingFunction {
private class Fprintf extends FormattingFunction, NonCppThrowingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
@@ -52,14 +50,12 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction {
override int getFormatParameterIndex() { result = 1 }
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
override TCxxException getExceptionType() { any() }
}
/**
* The standard function `sprintf` and its Microsoft and glib variants.
*/
private class Sprintf extends FormattingFunction, NonThrowingFunction {
private class Sprintf extends FormattingFunction, NonCppThrowingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
@@ -97,14 +93,14 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction {
then result = 4
else result = super.getFirstFormatArgumentIndex()
}
override TCxxException getExceptionType() { any() }
}
/**
* Implements `Snprintf`.
*/
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction {
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction,
NonCppThrowingFunction
{
SnprintfImpl() {
this instanceof TopLevelFunction and
(
@@ -171,8 +167,6 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction,
// We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects.
i = this.getFormatParameterIndex() and buffer = true
}
override TCxxException getExceptionType() { any() }
}
/**
@@ -213,7 +207,7 @@ private class StringCchPrintf extends FormattingFunction {
/**
* The standard function `syslog`.
*/
private class Syslog extends FormattingFunction, NonThrowingFunction {
private class Syslog extends FormattingFunction, NonCppThrowingFunction {
Syslog() {
this instanceof TopLevelFunction and
this.hasGlobalName("syslog") and
@@ -223,6 +217,4 @@ private class Syslog extends FormattingFunction, NonThrowingFunction {
override int getFormatParameterIndex() { result = 1 }
override predicate isOutputGlobal() { any() }
override TCxxException getExceptionType() { any() }
}

View File

@@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard function `strcat` and its wide, sized, and Microsoft variants.
@@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Throwing
* Does not include `strlcat`, which is covered by `StrlcatFunction`
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction,
NonThrowingFunction
NonCppThrowingFunction
{
StrcatFunction() {
this.hasGlobalOrStdOrBslName([
@@ -94,8 +94,6 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
(i = 0 or i = 1) and
buffer = true
}
override TCxxException getExceptionType() { any() }
}
/**

View File

@@ -7,13 +7,13 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Throwing
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* The standard function `strcpy` and its wide, sized, and Microsoft variants.
*/
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction,
NonThrowingFunction
NonCppThrowingFunction
{
StrcpyFunction() {
this.hasGlobalOrStdOrBslName([
@@ -145,6 +145,4 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
i = this.getParamDest() and
result = this.getParamSize()
}
override TCxxException getExceptionType() { any() }
}

View File

@@ -1,11 +1,7 @@
import semmle.code.cpp.models.interfaces.Throwing
class WindowsDriverExceptionAnnotation extends ThrowingFunction {
class WindowsDriverExceptionAnnotation extends AlwaysSehThrowingFunction {
WindowsDriverExceptionAnnotation() {
this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"])
}
override predicate mayThrowException(boolean unconditional) { unconditional = true }
override TSehException getExceptionType() { any() }
}

View File

@@ -5,9 +5,16 @@
import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
/**
* A function that is guaranteed to never throw a C++ exception
*
* The function may still raise a structured exception handling (SEH) exception.
*/
abstract class NonCppThrowingFunction extends Function { }
/**
* A function that is guaranteed to never throw.
*
* DEPRECATED: use `NonThrowingFunction` in `semmle.code.cpp.models.Models.Interfaces.Throwing` instead.
* DEPRECATED: use `NonCppThrowingFunction` instead.
*/
abstract deprecated class NonThrowingFunction extends Function { }
deprecated class NonThrowingFunction = NonCppThrowingFunction;

View File

@@ -11,65 +11,17 @@ import semmle.code.cpp.models.Models
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* Represents a type of exception,
* either Structured Exception Handling (SEH) or C++ exceptions.
* A function that is known to raise an exception.
*/
newtype TException =
/** Structured Exception Handling (SEH) exception */
TSehException() or
/** C++ exception */
TCxxException()
/**
* Functions with information about how an exception is thrown or if one is thrown at all.
* If throwing details conflict for the same function, IR is assumed
* to use the most restricted interpretation, meaning taking options
* that stipulate no exception is raised, before the exception is always raised,
* before conditional exceptions.
*
* Annotations must specify if the exception is from SEH (structured exception handling)
* or ordinary c++ exceptions.
*/
abstract private class ExceptionAnnotation extends Function {
abstract class ThrowingFunction extends Function {
/**
* Returns the type of exception this annotation is for,
* either a CPP exception or a STructured Exception Handling (SEH) exception.
*/
abstract TException getExceptionType();
/**
* Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception.
*/
final predicate isSeh() { this.getExceptionType() = TSehException() }
/**
* Holds if the exception type of this annotation is for a CPP exception.
*/
final predicate isCxx() { this.getExceptionType() = TCxxException() }
}
/**
* A Function that is known to not throw an exception.
*/
abstract class NonThrowingFunction extends ExceptionAnnotation { }
/**
* A function this is known to raise an exception.
*/
abstract class ThrowingFunction extends ExceptionAnnotation {
ThrowingFunction() { any() }
/**
* Holds if this function may raise an exception during evaluation.
* If `unconditional` is `false` the function may raise, and if `true` the function
* will always raise an exception.
* Do not specify `none()` if no exception is raised, instead use the
* `NonThrowingFunction` class instead.
* Holds if this function may throw an exception during evaluation.
* If `unconditional` is `true` the function always throws an exception.
*/
abstract predicate mayThrowException(boolean unconditional);
/**
* Holds if this function will always raise an exception if called
*/
final predicate alwaysThrowsException() { this.mayThrowException(true) }
}
/**
* A function that unconditionally raises a structured exception handling (SEH) exception.
*/
abstract class AlwaysSehThrowingFunction extends Function { }

View File

@@ -45,7 +45,7 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) {
* like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier.
*/
predicate functionMayThrow(Function f) {
not f instanceof NonThrowingFunction and
not f instanceof NonCppThrowingFunction and
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock()))
}