Skip to content

Commit 4b2758f

Browse files
committed
Merge branch 'main' into skip-safe-conversions-in-range-analysis
2 parents 724d97e + 12b236f commit 4b2758f

File tree

36 files changed

+984
-264
lines changed

36 files changed

+984
-264
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,29 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
10391039
or
10401040
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
10411041
)
1042+
or
1043+
exists(
1044+
SemRemExpr rem, SemZeroBound b1, SemZeroBound b2, D::Delta d_max, D::Delta d1, D::Delta d2,
1045+
boolean fbe1, boolean fbe2, D::Delta od1, D::Delta od2, SemReason r1, SemReason r2
1046+
|
1047+
rem = e and
1048+
not (upper = true and semPositive(rem.getRightOperand())) and
1049+
not (upper = true and semPositive(rem.getLeftOperand())) and
1050+
boundedRemExpr(rem, b1, true, d1, fbe1, od1, r1) and
1051+
boundedRemExpr(rem, b2, false, d2, fbe2, od2, r2) and
1052+
(
1053+
if D::toFloat(d1).abs() > D::toFloat(d2).abs()
1054+
then (
1055+
b = b1 and d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1
1056+
) else (
1057+
b = b2 and d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2
1058+
)
1059+
)
1060+
|
1061+
upper = true and delta = D::fromFloat(D::toFloat(d_max).abs() - 1)
1062+
or
1063+
upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1)
1064+
)
10421065
)
10431066
}
10441067

@@ -1065,4 +1088,11 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig<
10651088
bounded(add.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
10661089
)
10671090
}
1091+
1092+
private predicate boundedRemExpr(
1093+
SemRemExpr rem, SemZeroBound b, boolean upper, D::Delta delta, boolean fromBackEdge,
1094+
D::Delta origdelta, SemReason reason
1095+
) {
1096+
bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
1097+
}
10681098
}

cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@ int test2(struct List* p) {
1818
int count = 0;
1919
for (; p; p = p->next) {
2020
count = (count+1) % 10;
21-
range(count); // $ range=<=9 range=<=count:p+1
21+
range(count); // $ range=<=9 range=>=-9 range=<=count:p+1
2222
}
23-
range(count); // $ range=<=9
23+
range(count); // $ range=>=-9 range=<=9
2424
return count;
2525
}
2626

2727
int test3(struct List* p) {
2828
int count = 0;
2929
for (; p; p = p->next) {
30-
range(count++); // $ range=<=9
30+
range(count++); // $ range=>=-9 range=<=9
3131
count = count % 10;
32-
range(count); // $ range=<=9 range="<=... +++0" range=<=count:p+1
32+
range(count); // $ range=<=9 range=>=-9 range="<=... +++0" range=<=count:p+1
3333
}
34-
range(count); // $ range=<=9
34+
range(count); // $ range=>=-9 range=<=9
3535
return count;
3636
}
3737

@@ -964,7 +964,22 @@ void guard_bound_out_of_range(void) {
964964

965965
void test_mod(int s) {
966966
int s2 = s % 5;
967-
range(s2); // $ range=<=4 // -4 .. 4
967+
range(s2); // $ range=>=-4 range=<=4
968+
}
969+
970+
void test_mod_neg(int s) {
971+
int s2 = s % -5;
972+
range(s2); // $ range=>=-4 range=<=4
973+
}
974+
975+
void test_mod_ternary(int s, bool b) {
976+
int s2 = s % (b ? 5 : 500);
977+
range(s2); // $ range=>=-499 range=<=499 range="<=... ? ... : ...-1"
978+
}
979+
980+
void test_mod_ternary2(int s, bool b1, bool b2) {
981+
int s2 = s % (b1 ? (b2 ? 5 : -5000) : -500000);
982+
range(s2); // $ range=>=-499999 range=<=499999
968983
}
969984

970985
void exit(int);

csharp/ql/lib/semmle/code/asp/WebConfig.qll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ class WebConfigXml extends XmlFile {
1111
WebConfigXml() { this.getName().matches("%Web.config") }
1212
}
1313

14+
/**
15+
* A `Web.config` transformation file.
16+
*/
17+
class WebConfigReleaseTransformXml extends XmlFile {
18+
WebConfigReleaseTransformXml() { this.getName().matches("%Web.Release.config") }
19+
}
20+
1421
/** DEPRECATED: Alias for WebConfigXml */
1522
deprecated class WebConfigXML = WebConfigXml;
1623

@@ -19,6 +26,11 @@ class ConfigurationXmlElement extends XmlElement {
1926
ConfigurationXmlElement() { this.getName().toLowerCase() = "configuration" }
2027
}
2128

29+
/** A `<compilation>` tag in an ASP.NET configuration file. */
30+
class CompilationXmlElement extends XmlElement {
31+
CompilationXmlElement() { this.getName().toLowerCase() = "compilation" }
32+
}
33+
2234
/** DEPRECATED: Alias for ConfigurationXmlElement */
2335
deprecated class ConfigurationXMLElement = ConfigurationXmlElement;
2436

@@ -149,3 +161,15 @@ class HttpCookiesElement extends XmlElement {
149161
/** DEPRECATED: Alias for isRequireSsl */
150162
deprecated predicate isRequireSSL() { this.isRequireSsl() }
151163
}
164+
165+
/** A `Transform` attribute in a Web.config transformation file. */
166+
class TransformXmlAttribute extends XmlAttribute {
167+
TransformXmlAttribute() { this.getName().toLowerCase() = "transform" }
168+
169+
/**
170+
* Gets the list of attribute removals in `Transform=RemoveAttributes(list)`.
171+
*/
172+
string getRemoveAttributes() {
173+
result = this.getValue().regexpCapture("RemoveAttributes\\((.*)\\)", 1).splitAt(",")
174+
}
175+
}

csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ import semmle.code.asp.WebConfig
1919

2020
from SystemWebXmlElement web, XmlAttribute debugAttribute
2121
where
22-
debugAttribute = web.getAChild("compilation").getAttribute("debug") and
23-
not debugAttribute.getValue().toLowerCase() = "false"
22+
exists(CompilationXmlElement compilation | compilation.getParent() = web |
23+
debugAttribute = compilation.getAttribute("debug") and
24+
not debugAttribute.getValue().toLowerCase() = "false"
25+
) and
26+
not exists(
27+
TransformXmlAttribute attribute, CompilationXmlElement compilation,
28+
WebConfigReleaseTransformXml file
29+
|
30+
compilation = attribute.getElement() and
31+
file = compilation.getFile() and
32+
attribute.getRemoveAttributes() = "debug" and
33+
file.getParentContainer() = web.getFile().getParentContainer()
34+
)
2435
select debugAttribute, "The 'debug' flag is set for an ASP.NET configuration file."
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `cs/web/debug-binary` now disregards the `debug` attribute in case there is a transformation that removes it.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
| bad/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. |
1+
| bad1/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. |
2+
| bad2/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
3+
<system.web>
4+
<compilation xdt:Transform="RemoveAttributes(debug)" />
5+
</system.web>
6+
</configuration>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<system.web>
4+
<compilation
5+
defaultLanguage="c#"
6+
debug="true"
7+
/>
8+
</system.web>
9+
</configuration>

0 commit comments

Comments
 (0)