Skip to content

Commit c1302a9

Browse files
committed
Ruby: use MaD for more precise Pathname flow summaries
1 parent 280c959 commit c1302a9

File tree

3 files changed

+375
-202
lines changed

3 files changed

+375
-202
lines changed

ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll

Lines changed: 67 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import codeql.ruby.Concepts
66
private import codeql.ruby.DataFlow
77
private import codeql.ruby.dataflow.FlowSummary
88
private import codeql.ruby.dataflow.internal.DataFlowDispatch
9+
private import codeql.ruby.frameworks.data.ModelsAsData
910

1011
/**
1112
* Modeling of the `Pathname` class from the Ruby standard library.
@@ -113,106 +114,75 @@ module Pathname {
113114
override DataFlow::Node getAPermissionNode() { result = permissionArg }
114115
}
115116

116-
/** Flow summary for `Pathname.new`. */
117-
private class NewSummary extends SummarizedCallable {
118-
NewSummary() { this = "Pathname.new" }
119-
120-
override MethodCall getACall() {
121-
result = API::getTopLevelMember("Pathname").getAnInstantiation().getExprNode().getExpr()
122-
}
123-
124-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
125-
input = "Argument[0]" and
126-
output = "ReturnValue" and
127-
preservesValue = false
128-
}
129-
}
130-
131-
/** Flow summary for `Pathname#dirname`. */
132-
private class DirnameSummary extends SimpleSummarizedCallable {
133-
DirnameSummary() { this = "dirname" }
134-
135-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
136-
input = "Argument[self]" and
137-
output = "ReturnValue" and
138-
preservesValue = false
139-
}
140-
}
141-
142-
/** Flow summary for `Pathname#each_filename`. */
143-
private class EachFilenameSummary extends SimpleSummarizedCallable {
144-
EachFilenameSummary() { this = "each_filename" }
145-
146-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
147-
input = "Argument[self]" and
148-
output = "Argument[block].Parameter[0]" and
149-
preservesValue = false
150-
}
151-
}
152-
153-
/** Flow summary for `Pathname#expand_path`. */
154-
private class ExpandPathSummary extends SimpleSummarizedCallable {
155-
ExpandPathSummary() { this = "expand_path" }
156-
157-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
158-
input = "Argument[self]" and
159-
output = "ReturnValue" and
160-
preservesValue = false
161-
}
162-
}
163-
164-
/** Flow summary for `Pathname#join`. */
165-
private class JoinSummary extends SimpleSummarizedCallable {
166-
JoinSummary() { this = "join" }
167-
168-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
169-
input = ["Argument[self]", "Argument[any]"] and
170-
output = "ReturnValue" and
171-
preservesValue = false
172-
}
173-
}
174-
175-
/** Flow summary for `Pathname#parent`. */
176-
private class ParentSummary extends SimpleSummarizedCallable {
177-
ParentSummary() { this = "parent" }
178-
179-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
180-
input = "Argument[self]" and
181-
output = "ReturnValue" and
182-
preservesValue = false
183-
}
184-
}
185-
186-
/** Flow summary for `Pathname#realpath`. */
187-
private class RealpathSummary extends SimpleSummarizedCallable {
188-
RealpathSummary() { this = "realpath" }
189-
190-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
191-
input = "Argument[self]" and
192-
output = "ReturnValue" and
193-
preservesValue = false
194-
}
195-
}
196-
197-
/** Flow summary for `Pathname#relative_path_from`. */
198-
private class RelativePathFromSummary extends SimpleSummarizedCallable {
199-
RelativePathFromSummary() { this = "relative_path_from" }
200-
201-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
202-
input = "Argument[self]" and
203-
output = "ReturnValue" and
204-
preservesValue = false
117+
/**
118+
* Type summaries for the `Pathname` class, i.e. method calls that produce new
119+
* `Pathname` instances.
120+
*/
121+
private class PathnameTypeSummary extends ModelInput::TypeModelCsv {
122+
override predicate row(string row) {
123+
// package1;type1;package2;type2;path
124+
row =
125+
[
126+
// Pathname.new : Pathname
127+
";Pathname;;;Member[Pathname].Instance",
128+
// Pathname#+(path) : Pathname
129+
";Pathname;;Pathname;Method[+].ReturnValue",
130+
// Pathname#/(path) : Pathname
131+
";Pathname;;Pathname;Method[/].ReturnValue",
132+
// Pathname#basename(path) : Pathname
133+
";Pathname;;Pathname;Method[basename].ReturnValue",
134+
// Pathname#cleanpath(path) : Pathname
135+
";Pathname;;Pathname;Method[cleanpath].ReturnValue",
136+
// Pathname#expand_path(path) : Pathname
137+
";Pathname;;Pathname;Method[expand_path].ReturnValue",
138+
// Pathname#join(path) : Pathname
139+
";Pathname;;Pathname;Method[join].ReturnValue",
140+
// Pathname#realpath(path) : Pathname
141+
";Pathname;;Pathname;Method[realpath].ReturnValue",
142+
// Pathname#relative_path_from(path) : Pathname
143+
";Pathname;;Pathname;Method[relative_path_from].ReturnValue",
144+
// Pathname#sub(path) : Pathname
145+
";Pathname;;Pathname;Method[sub].ReturnValue",
146+
// Pathname#sub_ext(path) : Pathname
147+
";Pathname;;Pathname;Method[sub_ext].ReturnValue",
148+
// Pathname#to_path(path) : Pathname
149+
";Pathname;;Pathname;Method[to_path].ReturnValue",
150+
]
205151
}
206152
}
207153

208-
/** Flow summary for `Pathname#to_path`. */
209-
private class ToPathSummary extends SimpleSummarizedCallable {
210-
ToPathSummary() { this = "to_path" }
211-
212-
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
213-
input = "Argument[self]" and
214-
output = "ReturnValue" and
215-
preservesValue = false
154+
/** Taint flow summaries for the `Pathname` class. */
155+
private class PathnameTaintSummary extends ModelInput::SummaryModelCsv {
156+
override predicate row(string row) {
157+
row =
158+
[
159+
// Pathname.new(path)
160+
";;Member[Pathname].Method[new];Argument[0];ReturnValue;taint",
161+
// Pathname#dirname
162+
";Pathname;Method[dirname];Argument[self];ReturnValue;taint",
163+
// Pathname#each_filename
164+
";Pathname;Method[each_filename];Argument[self];Argument[block].Parameter[0];taint",
165+
// Pathname#expand_path
166+
";Pathname;Method[expand_path];Argument[self];ReturnValue;taint",
167+
// Pathname#join
168+
";Pathname;Method[join];Argument[self,any];ReturnValue;taint",
169+
// Pathname#parent
170+
";Pathname;Method[parent];Argument[self];ReturnValue;taint",
171+
// Pathname#realpath
172+
";Pathname;Method[realpath];Argument[self];ReturnValue;taint",
173+
// Pathname#relative_path_from
174+
";Pathname;Method[relative_path_from];Argument[self];ReturnValue;taint",
175+
// Pathname#to_path
176+
";Pathname;Method[to_path];Argument[self];ReturnValue;taint",
177+
// Pathname#basename
178+
";Pathname;Method[basename];Argument[self];ReturnValue;taint",
179+
// Pathname#cleanpath
180+
";Pathname;Method[cleanpath];Argument[self];ReturnValue;taint",
181+
// Pathname#sub
182+
";Pathname;Method[sub];Argument[self];ReturnValue;taint",
183+
// Pathname#sub_ext
184+
";Pathname;Method[sub_ext];Argument[self];ReturnValue;taint",
185+
]
216186
}
217187
}
218188
}

0 commit comments

Comments
 (0)