Skip to content

Commit e6b1e8e

Browse files
committed
Rust: Check call arities in path resolution
1 parent 92cced2 commit e6b1e8e

File tree

9 files changed

+75
-67
lines changed

9 files changed

+75
-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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,15 @@ 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()) }
2030
}
2131
}

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: 36 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 called with arguments. */
609+
abstract class CallableItemNode extends ItemNode {
610+
/** Gets the number of parameters of this item. */
611+
abstract int getNumberOfParameters();
612+
}
613+
614+
private class VariantItemNode extends CallableItemNode instanceof Variant {
608615
override string getName() { result = Variant.super.getName().getText() }
609616

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

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

627+
override int getNumberOfParameters() {
628+
result = super.getFieldList().(TupleFieldList).getNumberOfFields()
629+
}
630+
620631
override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
621632

622633
bindingset[c]
@@ -638,7 +649,7 @@ private class VariantItemNode extends ItemNode instanceof Variant {
638649
}
639650
}
640651

641-
class FunctionItemNode extends AssocItemNode instanceof Function {
652+
class FunctionItemNode extends AssocItemNode, CallableItemNode instanceof Function {
642653
override string getName() { result = Function.super.getName().getText() }
643654

644655
override predicate hasImplementation() { Function.super.hasImplementation() }
@@ -648,6 +659,13 @@ class FunctionItemNode extends AssocItemNode instanceof Function {
648659
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
649660

650661
override Visibility getVisibility() { result = Function.super.getVisibility() }
662+
663+
override int getNumberOfParameters() {
664+
exists(int arr |
665+
arr = super.getNumberOfParams() and
666+
if super.hasSelfParam() then result = arr + 1 else result = arr
667+
)
668+
}
651669
}
652670

653671
abstract class ImplOrTraitItemNode extends ItemNode {
@@ -712,8 +730,10 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
712730
TypeParamItemNode getBlanketImplementationTypeParam() { result = this.resolveSelfTy() }
713731

714732
/**
715-
* Holds if this impl block is a blanket implementation. That is, the
733+
* Holds if this impl block is a [blanket implementation][1]. That is, the
716734
* implementation targets a generic parameter of the impl block.
735+
*
736+
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
717737
*/
718738
predicate isBlanketImplementation() { exists(this.getBlanketImplementationTypeParam()) }
719739

@@ -865,7 +885,7 @@ private class ImplItemNodeImpl extends ImplItemNode {
865885
TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
866886
}
867887

868-
private class StructItemNode extends TypeItemNode instanceof Struct {
888+
private class StructItemNode extends TypeItemNode, CallableItemNode instanceof Struct {
869889
override string getName() { result = Struct.super.getName().getText() }
870890

871891
override Namespace getNamespace() {
@@ -877,6 +897,10 @@ private class StructItemNode extends TypeItemNode instanceof Struct {
877897

878898
override Visibility getVisibility() { result = Struct.super.getVisibility() }
879899

900+
override int getNumberOfParameters() {
901+
result = super.getFieldList().(TupleFieldList).getNumberOfFields()
902+
}
903+
880904
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
881905

882906
override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
@@ -1687,6 +1711,14 @@ private ItemNode resolvePathCand(RelevantPath path) {
16871711
or
16881712
not pathUsesNamespace(path, _) and
16891713
not path = any(MacroCall mc).getPath()
1714+
) and
1715+
(
1716+
not path = CallExprImpl::getFunctionPath(_)
1717+
or
1718+
exists(CallExpr ce |
1719+
path = CallExprImpl::getFunctionPath(ce) and
1720+
result.(CallableItemNode).getNumberOfParameters() = ce.getNumberOfArgs()
1721+
)
16901722
)
16911723
}
16921724

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ module Consistency {
230230
// Suppress the inconsistency if `n` is a self parameter and the type
231231
// mention for the self type has multiple types for a path.
232232
not exists(ImplItemNode impl, TypePath selfTypePath |
233-
n = impl.getAnAssocItem().(Function).getParamList().getSelfParam() and
233+
n = impl.getAnAssocItem().(Function).getSelfParam() and
234234
strictcount(impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(selfTypePath)) > 1
235235
)
236236
}
@@ -948,7 +948,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
948948
)
949949
or
950950
exists(SelfParam self |
951-
self = pragma[only_bind_into](this.getParamList().getSelfParam()) and
951+
self = pragma[only_bind_into](this.getSelfParam()) and
952952
dpos.isSelf() and
953953
result = inferAnnotatedType(self, path) // `self` parameter with type annotation
954954
)
@@ -972,7 +972,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
972972
exists(ImplOrTraitItemNode i |
973973
this = i.getAnAssocItem() and
974974
dpos.isSelf() and
975-
not this.getParamList().hasSelfParam()
975+
not this.hasSelfParam()
976976
|
977977
result = TSelfTypeParameter(i) and
978978
path.isEmpty()
@@ -1900,7 +1900,7 @@ private predicate methodCandidate(Type type, string name, int arity, Impl impl)
19001900
type = impl.getSelfTy().(TypeMention).resolveType() and
19011901
exists(Function f |
19021902
f = impl.(ImplItemNode).getASuccessor(name) and
1903-
f.getParamList().hasSelfParam() and
1903+
f.hasSelfParam() and
19041904
arity = f.getParamList().getNumberOfParams()
19051905
)
19061906
}
@@ -2222,7 +2222,7 @@ private module BlanketImplementation {
22222222
) {
22232223
isCanonicalImpl(impl) and
22242224
blanketImplementationTraitBound(impl, traitBound) and
2225-
f.getParamList().hasSelfParam() and
2225+
f.hasSelfParam() and
22262226
arity = f.getParamList().getNumberOfParams() and
22272227
(
22282228
f = impl.getAssocItem(name)
@@ -2332,7 +2332,7 @@ private Function resolveMethodCallTarget(MethodCall mc) {
23322332
pragma[nomagic]
23332333
private predicate assocFuncResolutionDependsOnArgument(Function f, Impl impl, int pos) {
23342334
functionResolutionDependsOnArgument(impl, _, f, pos, _, _) and
2335-
not f.getParamList().hasSelfParam()
2335+
not f.hasSelfParam()
23362336
}
23372337

23382338
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)