Skip to content

Commit de05aee

Browse files
committed
Adding model transition to using Throwing.qll.
1 parent 6785b93 commit de05aee

File tree

10 files changed

+112
-27
lines changed

10 files changed

+112
-27
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,11 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
363363
}
364364

365365
final override predicate mayThrowException() {
366-
expr.getTarget().(ThrowingFunction).mayThrowException(_)
366+
expr.getTarget().(ThrowingFunction).mayRaiseException()
367367
}
368368

369369
final override predicate mustThrowException() {
370-
expr.getTarget().(ThrowingFunction).mayThrowException(true)
370+
expr.getTarget().(ThrowingFunction).alwaysRaisesException()
371371
}
372372
}
373373

cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import semmle.code.cpp.models.interfaces.DataFlow
99
import semmle.code.cpp.models.interfaces.Alias
1010
import semmle.code.cpp.models.interfaces.SideEffect
1111
import semmle.code.cpp.models.interfaces.Taint
12-
import semmle.code.cpp.models.interfaces.NonThrowing
12+
import semmle.code.cpp.models.interfaces.Throwing
1313

1414
/**
1515
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
@@ -106,6 +106,8 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
106106
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
107107
index = this.getParamDest()
108108
}
109+
110+
override TCxxException getExceptionType() { any() }
109111
}
110112

111113
private string mempcpy() { result = ["mempcpy", "wmempcpy"] }

cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
88
import semmle.code.cpp.models.interfaces.DataFlow
99
import semmle.code.cpp.models.interfaces.Alias
1010
import semmle.code.cpp.models.interfaces.SideEffect
11-
import semmle.code.cpp.models.interfaces.NonThrowing
11+
import semmle.code.cpp.models.interfaces.Throwing
1212

1313
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
1414
SideEffectFunction, NonThrowingFunction
@@ -74,6 +74,8 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
7474
i = 0 and
7575
if this.hasGlobalName(bzero()) then result = 1 else result = 2
7676
}
77+
78+
override TCxxException getExceptionType() { any() }
7779
}
7880

7981
private string bzero() { result = ["bzero", "explicit_bzero"] }

cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import semmle.code.cpp.models.interfaces.NonThrowing
1+
import semmle.code.cpp.models.interfaces.Throwing
22

33
/**
44
* A function that is annotated with a `noexcept` specifier (or the equivalent
@@ -8,4 +8,6 @@ import semmle.code.cpp.models.interfaces.NonThrowing
88
*/
99
class NoexceptFunction extends NonThrowingFunction {
1010
NoexceptFunction() { this.isNoExcept() or this.isNoThrow() }
11+
12+
override TCxxException getExceptionType() { any() }
1113
}

cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import semmle.code.cpp.models.interfaces.FormattingFunction
99
import semmle.code.cpp.models.interfaces.Alias
1010
import semmle.code.cpp.models.interfaces.SideEffect
11-
import semmle.code.cpp.models.interfaces.NonThrowing
11+
import semmle.code.cpp.models.interfaces.Throwing
1212

1313
/**
1414
* The standard functions `printf`, `wprintf` and their glib variants.
@@ -32,6 +32,8 @@ private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunct
3232
override predicate parameterEscapesOnlyViaReturn(int n) { none() }
3333

3434
override predicate parameterIsAlwaysReturned(int n) { none() }
35+
36+
override TCxxException getExceptionType() { any() }
3537
}
3638

3739
/**
@@ -50,6 +52,8 @@ private class Fprintf extends FormattingFunction, NonThrowingFunction {
5052
override int getFormatParameterIndex() { result = 1 }
5153

5254
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
55+
56+
override TCxxException getExceptionType() { any() }
5357
}
5458

5559
/**
@@ -93,6 +97,8 @@ private class Sprintf extends FormattingFunction, NonThrowingFunction {
9397
then result = 4
9498
else result = super.getFirstFormatArgumentIndex()
9599
}
100+
101+
override TCxxException getExceptionType() { any() }
96102
}
97103

98104
/**
@@ -165,6 +171,8 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction,
165171
// We don't know how many parameters are passed to the function since it's varargs, but they also have read side effects.
166172
i = this.getFormatParameterIndex() and buffer = true
167173
}
174+
175+
override TCxxException getExceptionType() { any() }
168176
}
169177

170178
/**
@@ -215,4 +223,6 @@ private class Syslog extends FormattingFunction, NonThrowingFunction {
215223
override int getFormatParameterIndex() { result = 1 }
216224

217225
override predicate isOutputGlobal() { any() }
226+
227+
override TCxxException getExceptionType() { any() }
218228
}

cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
77
import semmle.code.cpp.models.interfaces.DataFlow
88
import semmle.code.cpp.models.interfaces.Taint
99
import semmle.code.cpp.models.interfaces.SideEffect
10-
import semmle.code.cpp.models.interfaces.NonThrowing
10+
import semmle.code.cpp.models.interfaces.Throwing
1111

1212
/**
1313
* The standard function `strcat` and its wide, sized, and Microsoft variants.
@@ -94,6 +94,8 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
9494
(i = 0 or i = 1) and
9595
buffer = true
9696
}
97+
98+
override TCxxException getExceptionType() { any() }
9799
}
98100

99101
/**

cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
77
import semmle.code.cpp.models.interfaces.DataFlow
88
import semmle.code.cpp.models.interfaces.Taint
99
import semmle.code.cpp.models.interfaces.SideEffect
10-
import semmle.code.cpp.models.interfaces.NonThrowing
10+
import semmle.code.cpp.models.interfaces.Throwing
1111

1212
/**
1313
* The standard function `strcpy` and its wide, sized, and Microsoft variants.
@@ -145,4 +145,6 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
145145
i = this.getParamDest() and
146146
result = this.getParamSize()
147147
}
148+
149+
override TCxxException getExceptionType() { any() }
148150
}
Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
import semmle.code.cpp.models.interfaces.Throwing
22

3-
class WindowsDriverFunction extends ThrowingFunction {
4-
WindowsDriverFunction() {
3+
/**
4+
* The default behavior for Structured Exception Handling (SEH) is
5+
* any function may (conditionally) raise an exception.
6+
* NOTE: this can be overridden by for any specific function to make in
7+
* unconditional or non-throwing. IR generation will enforce
8+
* the most strict interpretation.
9+
*/
10+
class DefaultSehExceptionBehavior extends ThrowingFunction {
11+
DefaultSehExceptionBehavior() { any() }
12+
13+
override predicate raisesException(boolean unconditional) { unconditional = false }
14+
15+
override TSehException getExceptionType() { any() }
16+
}
17+
18+
class WindowsDriverExceptionAnnotation extends ThrowingFunction {
19+
WindowsDriverExceptionAnnotation() {
520
this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"])
621
}
722

8-
final override predicate mayThrowException(boolean unconditional) { unconditional = true }
23+
override predicate raisesException(boolean unconditional) { unconditional = true }
24+
25+
override TSehException getExceptionType() { any() }
926
}

cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll

Lines changed: 0 additions & 11 deletions
This file was deleted.

cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,71 @@ import semmle.code.cpp.models.Models
1111
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
1212

1313
/**
14-
* A class that models the exceptional behavior of a function.
14+
* Represents a type of exception,
15+
* either Structured Exception Handling (SEH) or C++ exceptions.
1516
*/
16-
abstract class ThrowingFunction extends Function {
17+
newtype TException =
18+
/** Structured Exception Handling (SEH) exception */
19+
TSehException() or
20+
/** C++ exception */
21+
TCxxException()
22+
23+
/**
24+
* Functions with information about how an exception is thrown or if one is thrown at all.
25+
* If throwing details conflict for the same function, IR is assumed
26+
* to use the most restricted interpretation, meaning taking options
27+
* that stipulate no exception is raised, before the exception is always raised,
28+
* before conditional exceptions.
29+
*
30+
* Annotations must specify if the exception is from SEH (structured exception handling)
31+
* or ordinary c++ exceptions.
32+
*/
33+
abstract private class ExceptionAnnotation extends Function {
34+
/**
35+
* Returns the type of exception this annotation is for,
36+
* either a CPP exception or a STructured Exception Handling (SEH) exception.
37+
*/
38+
abstract TException getExceptionType();
39+
40+
/**
41+
* Holds if the exception type of this annotation is for a Structured Exception Handling (SEH) exception.
42+
*/
43+
final predicate isSeh() { this.getExceptionType() = TSehException() }
44+
45+
/**
46+
* Holds if the exception type of this annotation is for a CPP exception.
47+
*/
48+
final predicate isCxx() { this.getExceptionType() = TCxxException() }
49+
}
50+
51+
/**
52+
* A Function that is known to not throw an exception.
53+
*/
54+
abstract class NonThrowingFunction extends ExceptionAnnotation { }
55+
56+
/**
57+
* A function this is known to raise an exception.
58+
*/
59+
abstract class ThrowingFunction extends ExceptionAnnotation {
60+
ThrowingFunction() { any() }
61+
62+
/**
63+
* Holds if this function may raise an exception during evaluation.
64+
* If `unconditional` is `false` the function may raise, and if `true` the function
65+
* will always raise an exception.
66+
* Do not specify `none()` if no exception is raised, instead use the
67+
* `NonThrowingFunction` class instead.
68+
*/
69+
abstract predicate raisesException(boolean unconditional);
70+
71+
/**
72+
* Holds if this function will always raise an exception if called
73+
*/
74+
final predicate alwaysRaisesException() { this.raisesException(true) }
75+
1776
/**
18-
* Holds if this function may throw an exception during evaluation.
19-
* If `unconditional` is `true` the function always throws an exception.
77+
* Holds if this function may raise an exception if called but
78+
* it is not guaranteed to do so. I.e., the function does not always raise an exception.
2079
*/
21-
abstract predicate mayThrowException(boolean unconditional);
80+
final predicate mayRaiseException() { this.raisesException(false) }
2281
}

0 commit comments

Comments
 (0)