Skip to content

Commit 615b0a0

Browse files
authored
Merge pull request #20502 from hvitved/rust/path-resolution-check-arity
Rust: Check call arities in path resolution
2 parents c52709a + 4c7b66c commit 615b0a0

File tree

9 files changed

+76
-67
lines changed

9 files changed

+76
-67
lines changed

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope
7777

7878
override AstNode getChildNode(int i) {
7979
i = 0 and
80-
result = this.getParamList().getSelfParam()
80+
result = this.getSelfParam()
8181
or
8282
result = this.getParam(i - 1)
8383
or

rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ module Impl {
102102
f = resolvePath(path) and
103103
path.getSegment().getIdentifier().getText() = methodName and
104104
exists(SelfParam self |
105-
self = f.getParamList().getSelfParam() and
105+
self = f.getSelfParam() and
106106
if self.isRef() then selfIsRef = true else selfIsRef = false
107107
)
108108
)

rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,25 @@ module Impl {
1717
*/
1818
class Callable extends Generated::Callable {
1919
override Param getParam(int index) { result = this.getParamList().getParam(index) }
20+
21+
/**
22+
* Gets the self parameter of this callable, if it exists.
23+
*/
24+
SelfParam getSelfParam() { result = this.getParamList().getSelfParam() }
25+
26+
/**
27+
* Holds if `getSelfParam()` exists.
28+
*/
29+
predicate hasSelfParam() { exists(this.getSelfParam()) }
30+
31+
/**
32+
* Gets the number of parameters of this callable, including `self` if it exists.
33+
*/
34+
int getNumberOfParamsInclSelf() {
35+
exists(int arr |
36+
arr = this.getNumberOfParams() and
37+
if this.hasSelfParam() then result = arr + 1 else result = arr
38+
)
39+
}
2040
}
2141
}

rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ module Impl {
109109
text = name.getText() and
110110
// exclude self parameters from functions without a body as these are
111111
// trait method declarations without implementations
112-
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
112+
not exists(Function f | not f.hasBody() and f.getSelfParam() = sp)
113113
)
114114
or
115115
exists(IdentPat pat |

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
private import rust
66
private import codeql.rust.elements.internal.generated.ParentChild
7+
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
78
private import codeql.rust.internal.CachedStages
89
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
910
private import codeql.util.Option
@@ -604,7 +605,13 @@ private class EnumItemNode extends TypeItemNode instanceof Enum {
604605
}
605606
}
606607

607-
private class VariantItemNode extends ItemNode instanceof Variant {
608+
/** An item that can be referenced with arguments. */
609+
abstract class ParameterizableItemNode extends ItemNode {
610+
/** Gets the arity this item. */
611+
abstract int getArity();
612+
}
613+
614+
private class VariantItemNode extends ParameterizableItemNode instanceof Variant {
608615
override string getName() { result = Variant.super.getName().getText() }
609616

610617
override Namespace getNamespace() {
@@ -617,6 +624,8 @@ private class VariantItemNode extends ItemNode instanceof Variant {
617624

618625
override Visibility getVisibility() { result = super.getEnum().getVisibility() }
619626

627+
override int getArity() { result = super.getFieldList().(TupleFieldList).getNumberOfFields() }
628+
620629
override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
621630

622631
bindingset[c]
@@ -638,7 +647,7 @@ private class VariantItemNode extends ItemNode instanceof Variant {
638647
}
639648
}
640649

641-
class FunctionItemNode extends AssocItemNode instanceof Function {
650+
class FunctionItemNode extends AssocItemNode, ParameterizableItemNode instanceof Function {
642651
override string getName() { result = Function.super.getName().getText() }
643652

644653
override predicate hasImplementation() { Function.super.hasImplementation() }
@@ -648,6 +657,8 @@ class FunctionItemNode extends AssocItemNode instanceof Function {
648657
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
649658

650659
override Visibility getVisibility() { result = Function.super.getVisibility() }
660+
661+
override int getArity() { result = super.getNumberOfParamsInclSelf() }
651662
}
652663

653664
abstract class ImplOrTraitItemNode extends ItemNode {
@@ -712,8 +723,10 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
712723
TypeParamItemNode getBlanketImplementationTypeParam() { result = this.resolveSelfTy() }
713724

714725
/**
715-
* Holds if this impl block is a blanket implementation. That is, the
726+
* Holds if this impl block is a [blanket implementation][1]. That is, the
716727
* implementation targets a generic parameter of the impl block.
728+
*
729+
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
717730
*/
718731
predicate isBlanketImplementation() { exists(this.getBlanketImplementationTypeParam()) }
719732

@@ -865,7 +878,7 @@ private class ImplItemNodeImpl extends ImplItemNode {
865878
TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
866879
}
867880

868-
private class StructItemNode extends TypeItemNode instanceof Struct {
881+
private class StructItemNode extends TypeItemNode, ParameterizableItemNode instanceof Struct {
869882
override string getName() { result = Struct.super.getName().getText() }
870883

871884
override Namespace getNamespace() {
@@ -877,6 +890,8 @@ private class StructItemNode extends TypeItemNode instanceof Struct {
877890

878891
override Visibility getVisibility() { result = Struct.super.getVisibility() }
879892

893+
override int getArity() { result = super.getFieldList().(TupleFieldList).getNumberOfFields() }
894+
880895
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
881896

882897
override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
@@ -1687,6 +1702,14 @@ private ItemNode resolvePathCand(RelevantPath path) {
16871702
or
16881703
not pathUsesNamespace(path, _) and
16891704
not path = any(MacroCall mc).getPath()
1705+
) and
1706+
(
1707+
not path = CallExprImpl::getFunctionPath(_)
1708+
or
1709+
exists(CallExpr ce |
1710+
path = CallExprImpl::getFunctionPath(ce) and
1711+
result.(ParameterizableItemNode).getArity() = ce.getNumberOfArgs()
1712+
)
16901713
)
16911714
}
16921715

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ module Consistency {
235235
// Suppress the inconsistency if `n` is a self parameter and the type
236236
// mention for the self type has multiple types for a path.
237237
not exists(ImplItemNode impl, TypePath selfTypePath |
238-
n = impl.getAnAssocItem().(Function).getParamList().getSelfParam() and
238+
n = impl.getAnAssocItem().(Function).getSelfParam() and
239239
strictcount(impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(selfTypePath)) > 1
240240
)
241241
}
@@ -953,7 +953,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
953953
)
954954
or
955955
exists(SelfParam self |
956-
self = pragma[only_bind_into](this.getParamList().getSelfParam()) and
956+
self = pragma[only_bind_into](this.getSelfParam()) and
957957
dpos.isSelf() and
958958
result = inferAnnotatedType(self, path) // `self` parameter with type annotation
959959
)
@@ -977,7 +977,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
977977
exists(ImplOrTraitItemNode i |
978978
this = i.getAnAssocItem() and
979979
dpos.isSelf() and
980-
not this.getParamList().hasSelfParam()
980+
not this.hasSelfParam()
981981
|
982982
result = TSelfTypeParameter(i) and
983983
path.isEmpty()
@@ -1905,7 +1905,7 @@ private predicate methodCandidate(Type type, string name, int arity, Impl impl)
19051905
type = impl.getSelfTy().(TypeMention).resolveType() and
19061906
exists(Function f |
19071907
f = impl.(ImplItemNode).getASuccessor(name) and
1908-
f.getParamList().hasSelfParam() and
1908+
f.hasSelfParam() and
19091909
arity = f.getParamList().getNumberOfParams()
19101910
)
19111911
}
@@ -2227,7 +2227,7 @@ private module BlanketImplementation {
22272227
) {
22282228
isCanonicalImpl(impl) and
22292229
blanketImplementationTraitBound(impl, traitBound) and
2230-
f.getParamList().hasSelfParam() and
2230+
f.hasSelfParam() and
22312231
arity = f.getParamList().getNumberOfParams() and
22322232
(
22332233
f = impl.getAssocItem(name)
@@ -2337,7 +2337,7 @@ private Function resolveMethodCallTarget(MethodCall mc) {
23372337
pragma[nomagic]
23382338
private predicate assocFuncResolutionDependsOnArgument(Function f, Impl impl, int pos) {
23392339
functionResolutionDependsOnArgument(impl, _, f, pos, _, _) and
2340-
not f.getParamList().hasSelfParam()
2340+
not f.hasSelfParam()
23412341
}
23422342

23432343
private class FunctionCallExpr extends CallImpl::CallExprCall {
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
11
multipleCallTargets
2-
| test_cipher.rs:20:27:20:48 | ...::new(...) |
3-
| test_cipher.rs:26:27:26:48 | ...::new(...) |
4-
| test_cipher.rs:29:27:29:48 | ...::new(...) |
5-
| test_cipher.rs:36:30:36:59 | ...::new(...) |
6-
| test_cipher.rs:39:30:39:63 | ...::new(...) |
72
| test_cipher.rs:114:23:114:50 | ...::new(...) |

rust/ql/test/query-tests/security/CWE-798/CONSISTENCY/PathResolutionConsistency.expected

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

0 commit comments

Comments
 (0)