Skip to content

Commit 4515d27

Browse files
committed
Merge branch 'main' of https://github.com/github/codeql into pr/erik-krogh/4220
2 parents 38679b6 + 9879c6c commit 4515d27

File tree

352 files changed

+18782
-9684
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

352 files changed

+18782
-9684
lines changed

change-notes/1.26/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
| Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. |
3232
| Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. |
3333
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, slash, and underscore are used. |
34+
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. |
3435

3536

3637
## Changes to libraries

cpp/ql/src/jsf/4.10 Classes/AV Rule 82.ql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ predicate dereferenceThis(Expr e) {
4545
or
4646
// `*this = ...` (where `=` is not overloaded, so an `AssignExpr`)
4747
dereferenceThis(e.(AssignExpr).getLValue())
48+
or
49+
// `e ? ... : ... `
50+
exists(ConditionalExpr cond |
51+
cond = e and
52+
dereferenceThis(cond.getThen()) and
53+
dereferenceThis(cond.getElse())
54+
)
55+
or
56+
// `..., ... `
57+
dereferenceThis(e.(CommaExpr).getRightOperand())
4858
}
4959

5060
/**

cpp/ql/src/semmle/code/cpp/exprs/Expr.qll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,3 +1268,31 @@ class SpaceshipExpr extends BinaryOperation, @spaceshipexpr {
12681268

12691269
override string getOperator() { result = "<=>" }
12701270
}
1271+
1272+
/**
1273+
* A C/C++ `co_await` expression.
1274+
* ```
1275+
* co_await foo();
1276+
* ```
1277+
*/
1278+
class CoAwaitExpr extends UnaryOperation, @co_await {
1279+
override string getAPrimaryQlClass() { result = "CoAwaitExpr" }
1280+
1281+
override string getOperator() { result = "co_await" }
1282+
1283+
override int getPrecedence() { result = 16 }
1284+
}
1285+
1286+
/**
1287+
* A C/C++ `co_yield` expression.
1288+
* ```
1289+
* co_yield 1;
1290+
* ```
1291+
*/
1292+
class CoYieldExpr extends UnaryOperation, @co_yield {
1293+
override string getAPrimaryQlClass() { result = "CoYieldExpr" }
1294+
1295+
override string getOperator() { result = "co_yield" }
1296+
1297+
override int getPrecedence() { result = 2 }
1298+
}

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import semmle.code.cpp.ir.IR
1111
private import semmle.code.cpp.controlflow.IRGuards
1212
private import semmle.code.cpp.models.interfaces.DataFlow
1313

14+
cached
1415
private newtype TIRDataFlowNode =
1516
TInstructionNode(Instruction i) or
1617
TOperandNode(Operand op) or
@@ -533,11 +534,11 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
533534
* data flow. It may have less flow than the `localFlowStep` predicate.
534535
*/
535536
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
536-
// Instruction -> Instruction flow
537-
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
538-
or
539537
// Operand -> Instruction flow
540-
simpleOperandLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
538+
simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
539+
or
540+
// Instruction -> Operand flow
541+
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
541542
}
542543

543544
pragma[noinline]
@@ -549,26 +550,20 @@ private predicate getFieldSizeOfClass(Class c, Type type, int size) {
549550
)
550551
}
551552

552-
private predicate simpleOperandLocalFlowStep(Operand opFrom, Instruction iTo) {
553-
// Certain dataflow steps (for instance `PostUpdateNode.getPreUpdateNode()`) generates flow to
554-
// operands, so we include dataflow from those operands to the "result" of the instruction (i.e., to
555-
// the instruction itself).
556-
exists(PostUpdateNode post |
557-
opFrom = post.getPreUpdateNode().asOperand() and
558-
iTo.getAnOperand() = opFrom
553+
private predicate isSingleFieldClass(Type type, Class cTo) {
554+
exists(int size |
555+
cTo.getSize() = size and
556+
getFieldSizeOfClass(cTo, type, size)
559557
)
560558
}
561559

562-
cached
563-
private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo) {
564-
iTo.(CopyInstruction).getSourceValue() = iFrom
560+
private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
561+
// Propagate flow from an instruction to its exact uses.
562+
opTo.getDef() = iFrom
565563
or
566-
iTo.(PhiInstruction).getAnOperand().getDef() = iFrom
567-
or
568-
// A read side effect is almost never exact since we don't know exactly how
569-
// much memory the callee will read.
570-
iTo.(ReadSideEffectInstruction).getSideEffectOperand().getAnyDef() = iFrom and
571-
not iFrom.isResultConflated()
564+
opTo = any(ReadSideEffectInstruction read).getSideEffectOperand() and
565+
not iFrom.isResultConflated() and
566+
iFrom = opTo.getAnyDef()
572567
or
573568
// Loading a single `int` from an `int *` parameter is not an exact load since
574569
// the parameter may point to an entire array rather than a single `int`. The
@@ -582,20 +577,38 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
582577
// leads to a phi node.
583578
exists(InitializeIndirectionInstruction init |
584579
iFrom = init and
585-
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = init and
580+
opTo.(LoadOperand).getAnyDef() = init and
586581
// Check that the types match. Otherwise we can get flow from an object to
587582
// its fields, which leads to field conflation when there's flow from other
588583
// fields to the object elsewhere.
589584
init.getParameter().getType().getUnspecifiedType().(DerivedType).getBaseType() =
590-
iTo.getResultType().getUnspecifiedType()
585+
opTo.getType().getUnspecifiedType()
586+
)
587+
or
588+
// Flow from stores to structs with a single field to a load of that field.
589+
exists(LoadInstruction load |
590+
load.getSourceValueOperand() = opTo and
591+
opTo.getAnyDef() = iFrom and
592+
isSingleFieldClass(iFrom.getResultType(), opTo.getType())
591593
)
594+
}
595+
596+
cached
597+
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
598+
iTo.(CopyInstruction).getSourceValueOperand() = opFrom
599+
or
600+
iTo.(PhiInstruction).getAnInputOperand() = opFrom
601+
or
602+
// A read side effect is almost never exact since we don't know exactly how
603+
// much memory the callee will read.
604+
iTo.(ReadSideEffectInstruction).getSideEffectOperand() = opFrom
592605
or
593606
// Treat all conversions as flow, even conversions between different numeric types.
594-
iTo.(ConvertInstruction).getUnary() = iFrom
607+
iTo.(ConvertInstruction).getUnaryOperand() = opFrom
595608
or
596-
iTo.(CheckedConvertOrNullInstruction).getUnary() = iFrom
609+
iTo.(CheckedConvertOrNullInstruction).getUnaryOperand() = opFrom
597610
or
598-
iTo.(InheritanceConversionInstruction).getUnary() = iFrom
611+
iTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
599612
or
600613
// A chi instruction represents a point where a new value (the _partial_
601614
// operand) may overwrite an old value (the _total_ operand), but the alias
@@ -608,7 +621,7 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
608621
//
609622
// Flow through the partial operand belongs in the taint-tracking libraries
610623
// for now.
611-
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
624+
iTo.getAnOperand().(ChiTotalOperand) = opFrom
612625
or
613626
// Add flow from write side-effects to non-conflated chi instructions through their
614627
// partial operands. From there, a `readStep` will find subsequent reads of that field.
@@ -623,24 +636,16 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
623636
// Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
624637
// `setX`, which will be melded into `p` through a chi instruction.
625638
exists(ChiInstruction chi | chi = iTo |
626-
chi.getPartialOperand().getDef() = iFrom.(WriteSideEffectInstruction) and
639+
opFrom.getAnyDef() instanceof WriteSideEffectInstruction and
640+
chi.getPartialOperand() = opFrom and
627641
not chi.isResultConflated()
628642
)
629643
or
630-
// Flow from stores to structs with a single field to a load of that field.
631-
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = iFrom and
632-
exists(int size, Type type, Class cTo |
633-
type = iFrom.getResultType() and
634-
cTo = iTo.getResultType() and
635-
cTo.getSize() = size and
636-
getFieldSizeOfClass(cTo, type, size)
637-
)
638-
or
639644
// Flow through modeled functions
640-
modelFlow(iFrom, iTo)
645+
modelFlow(opFrom, iTo)
641646
}
642647

643-
private predicate modelFlow(Instruction iFrom, Instruction iTo) {
648+
private predicate modelFlow(Operand opFrom, Instruction iTo) {
644649
exists(
645650
CallInstruction call, DataFlowFunction func, FunctionInput modelIn, FunctionOutput modelOut
646651
|
@@ -665,17 +670,17 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
665670
(
666671
exists(int index |
667672
modelIn.isParameter(index) and
668-
iFrom = call.getPositionalArgument(index)
673+
opFrom = call.getPositionalArgumentOperand(index)
669674
)
670675
or
671676
exists(int index, ReadSideEffectInstruction read |
672677
modelIn.isParameterDeref(index) and
673678
read = getSideEffectFor(call, index) and
674-
iFrom = read.getSideEffectOperand().getAnyDef()
679+
opFrom = read.getSideEffectOperand()
675680
)
676681
or
677682
modelIn.isQualifierAddress() and
678-
iFrom = call.getThisArgument()
683+
opFrom = call.getThisArgumentOperand()
679684
// TODO: add read side effects for qualifiers
680685
)
681686
)

cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,67 @@ class LabelStmt extends Stmt, @stmt_label {
662662
override predicate mayBeGloballyImpure() { none() }
663663
}
664664

665+
/**
666+
* A C/C++ `co_return` statement.
667+
*
668+
* For example:
669+
* ```
670+
* co_return 1+2;
671+
* ```
672+
* or
673+
* ```
674+
* co_return;
675+
* ```
676+
*/
677+
class CoReturnStmt extends Stmt, @stmt_co_return {
678+
override string getAPrimaryQlClass() { result = "CoReturnStmt" }
679+
680+
/**
681+
* Gets the operand of this 'co_return' statement.
682+
*
683+
* For example, for
684+
* ```
685+
* co_return 1+2;
686+
* ```
687+
* the operand is a function call `return_value(1+2)`, and for
688+
* ```
689+
* co_return;
690+
* ```
691+
* the operand is a function call `return_void()`.
692+
*/
693+
FunctionCall getOperand() { result = this.getChild(0) }
694+
695+
/**
696+
* Gets the expression of this 'co_return' statement, if any.
697+
*
698+
* For example, for
699+
* ```
700+
* co_return 1+2;
701+
* ```
702+
* the result is `1+2`, and there is no result for
703+
* ```
704+
* co_return;
705+
* ```
706+
*/
707+
Expr getExpr() { result = this.getOperand().getArgument(0) }
708+
709+
/**
710+
* Holds if this 'co_return' statement has an expression.
711+
*
712+
* For example, this holds for
713+
* ```
714+
* co_return 1+2;
715+
* ```
716+
* but not for
717+
* ```
718+
* co_return;
719+
* ```
720+
*/
721+
predicate hasExpr() { exists(this.getExpr()) }
722+
723+
override string toString() { result = "co_return ..." }
724+
}
725+
665726
/**
666727
* A C/C++ 'return' statement.
667728
*

cpp/ql/src/semmlecode.cpp.dbscheme

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,8 @@ funbind(
12281228
| @builtinaddressof
12291229
| @vec_fill
12301230
| @un_log_op_expr
1231+
| @co_await
1232+
| @co_yield
12311233
;
12321234

12331235
@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
@@ -1647,6 +1649,8 @@ case @expr.kind of
16471649
| 324 = @builtinconvertvector
16481650
| 325 = @builtincomplex
16491651
| 326 = @spaceshipexpr
1652+
| 327 = @co_await
1653+
| 328 = @co_yield
16501654
;
16511655

16521656
@var_args_expr = @vastartexpr
@@ -1851,6 +1855,7 @@ case @stmt.kind of
18511855
| 33 = @stmt_handler
18521856
// ... 34 @stmt_finally_end deprecated
18531857
| 35 = @stmt_constexpr_if
1858+
| 37 = @stmt_co_return
18541859
;
18551860

18561861
type_vla(

0 commit comments

Comments
 (0)