Merge pull request #3843 from geoffw0/qldoc6

C++: Bit more QLDoc
This commit is contained in:
Jonas Jensen
2020-06-30 16:21:37 +02:00
committed by GitHub
5 changed files with 98 additions and 25 deletions

View File

@@ -23,8 +23,7 @@ abstract class MutexType extends Type {
abstract predicate trylockAccess(FunctionCall fc, Expr arg);
/**
* Holds if `fc` is a call that unlocks mutex `arg`
* of this type.
* Holds if `fc` is a call that unlocks mutex `arg` of this type.
*/
abstract predicate unlockAccess(FunctionCall fc, Expr arg);
@@ -38,8 +37,7 @@ abstract class MutexType extends Type {
}
/**
* Holds if `fc` is a call that locks or tries to lock any
* mutex of this type.
* Gets a call that locks or tries to lock any mutex of this type.
*/
FunctionCall getLockAccess() {
result = getMustlockAccess() or
@@ -47,44 +45,44 @@ abstract class MutexType extends Type {
}
/**
* Holds if `fc` is a call that always locks any mutex of this type.
* Gets a call that always locks any mutex of this type.
*/
FunctionCall getMustlockAccess() { this.mustlockAccess(result, _) }
/**
* Holds if `fc` is a call that tries to lock any mutex of this type,
* Gets a call that tries to lock any mutex of this type,
* by may return without success.
*/
FunctionCall getTrylockAccess() { this.trylockAccess(result, _) }
/**
* Holds if `fc` is a call that unlocks any mutex of this type.
* Gets a call that unlocks any mutex of this type.
*/
FunctionCall getUnlockAccess() { this.unlockAccess(result, _) }
/**
* DEPRECATED: use mustlockAccess(fc, arg) instead
* DEPRECATED: use mustlockAccess(fc, arg) instead.
*/
deprecated Function getMustlockFunction() { result = getMustlockAccess().getTarget() }
/**
* DEPRECATED: use trylockAccess(fc, arg) instead
* DEPRECATED: use trylockAccess(fc, arg) instead.
*/
deprecated Function getTrylockFunction() { result = getTrylockAccess().getTarget() }
/**
* DEPRECATED: use lockAccess(fc, arg) instead
* DEPRECATED: use lockAccess(fc, arg) instead.
*/
deprecated Function getLockFunction() { result = getLockAccess().getTarget() }
/**
* DEPRECATED: use unlockAccess(fc, arg) instead
* DEPRECATED: use unlockAccess(fc, arg) instead.
*/
deprecated Function getUnlockFunction() { result = getUnlockAccess().getTarget() }
}
/**
* A function that looks like a lock function.
* Gets a function that looks like a lock function.
*/
private Function mustlockCandidate() {
exists(string name | name = result.getName() |
@@ -94,7 +92,7 @@ private Function mustlockCandidate() {
}
/**
* A function that looks like a try-lock function.
* Gets a function that looks like a try-lock function.
*/
private Function trylockCandidate() {
exists(string name | name = result.getName() |
@@ -104,7 +102,7 @@ private Function trylockCandidate() {
}
/**
* A function that looks like an unlock function.
* Gets a function that looks like an unlock function.
*/
private Function unlockCandidate() {
exists(string name | name = result.getName() |
@@ -171,7 +169,10 @@ class DefaultMutexType extends MutexType {
}
}
/** Get the mutex argument of a call to lock or unlock. */
/**
* Holds if `arg` is the mutex argument of a call to lock or unlock and
* `argType` is the type of the mutex.
*/
private predicate lockArg(Expr arg, MutexType argType, FunctionCall call) {
argType = arg.getUnderlyingType().stripType() and
(
@@ -184,18 +185,31 @@ private predicate lockArg(Expr arg, MutexType argType, FunctionCall call) {
// `MutexType.mustlockAccess`.
}
/**
* Holds if `call` is a call that locks or tries to lock its argument `arg`.
*/
predicate lockCall(Expr arg, FunctionCall call) {
exists(MutexType t | lockArg(arg, t, call) and call = t.getLockAccess())
}
/**
* Holds if `call` is a call that always locks its argument `arg`.
*/
predicate mustlockCall(Expr arg, FunctionCall call) {
exists(MutexType t | lockArg(arg, t, call) and call = t.getMustlockAccess())
}
/**
* Holds if `call` is a call that tries to lock its argument `arg`, but may
* return without success.
*/
predicate trylockCall(Expr arg, FunctionCall call) {
exists(MutexType t | lockArg(arg, t, call) and call = t.getTrylockAccess())
}
/**
* Holds if `call` is a call that unlocks its argument `arg`.
*/
predicate unlockCall(Expr arg, FunctionCall call) {
exists(MutexType t | lockArg(arg, t, call) and call = t.getUnlockAccess())
}

View File

@@ -1,3 +1,8 @@
/**
* Provides classes for modeling literals in the source code such as `0`, `'c'`
* or `"string"`.
*/
import semmle.code.cpp.exprs.Expr
/**

View File

@@ -1,3 +1,20 @@
/**
* Provides predicates for identifying functions that wrap other functions,
* passing the same arguments from the outer call into the inner call. In the
* following example `MyMalloc` wraps a call to `malloc`, passing in the `size`
* parameter:
* ```
* void *MyMalloc(size_t size)
* {
* void *ptr = malloc(size);
*
* // ... additional logic?
*
* return ptr;
* }
* ```
*/
import cpp
import PrintfLike
private import TaintTracking
@@ -152,6 +169,9 @@ abstract class FunctionWithWrappers extends Function {
}
}
/**
* A `printf`-like formatting function.
*/
class PrintfLikeFunction extends FunctionWithWrappers {
PrintfLikeFunction() { printfLikeFunction(this, _) }

View File

@@ -1,11 +1,14 @@
/**
* Provides predicates for reasoning about when the value of an expression is
* guarded by an operation such as `<`, which confines its range.
*/
import cpp
import semmle.code.cpp.controlflow.Dominance
/*
* Guarding
/**
* Holds if the value of `use` is guarded using `abs`.
*/
/** is the size of this use guarded using 'abs'? */
predicate guardedAbs(Operation e, Expr use) {
exists(FunctionCall fc | fc.getTarget().getName() = "abs" |
fc.getArgument(0).getAChild*() = use and
@@ -13,7 +16,10 @@ predicate guardedAbs(Operation e, Expr use) {
)
}
/** This is `BasicBlock.getNode`, restricted to `Stmt` for performance. */
/**
* Gets the position of `stmt` in basic block `block` (this is a thin layer
* over `BasicBlock.getNode`, intended to improve performance).
*/
pragma[noinline]
private int getStmtIndexInBlock(BasicBlock block, Stmt stmt) { block.getNode(result) = stmt }
@@ -30,7 +36,9 @@ private predicate stmtDominates(Stmt dominator, Stmt dominated) {
bbStrictlyDominates(dominator.getBasicBlock(), dominated.getBasicBlock())
}
/** is the size of this use guarded to be less than something? */
/**
* Holds if the value of `use` is guarded to be less than something.
*/
pragma[nomagic]
predicate guardedLesser(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard |
@@ -54,7 +62,9 @@ predicate guardedLesser(Operation e, Expr use) {
guardedAbs(e, use)
}
/** is the size of this use guarded to be greater than something? */
/**
* Holds if the value of `use` is guarded to be greater than something.
*/
pragma[nomagic]
predicate guardedGreater(Operation e, Expr use) {
exists(IfStmt c, RelationalOperation guard |
@@ -78,10 +88,14 @@ predicate guardedGreater(Operation e, Expr use) {
guardedAbs(e, use)
}
/** a use of a given variable */
/**
* Gets a use of a given variable `v`.
*/
VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
/** is e not guarded against overflow by use? */
/**
* Holds if `e` is not guarded against overflow by `use`.
*/
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
use = e.getAnOperand() and
exists(LocalScopeVariable v | use.getTarget() = v |
@@ -100,7 +114,9 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
)
}
/** is e not guarded against underflow by use? */
/**
* Holds if `e` is not guarded against underflow by `use`.
*/
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
use = e.getAnOperand() and
exists(LocalScopeVariable v | use.getTarget() = v |

View File

@@ -1,5 +1,14 @@
/**
* Provides classes for heuristically identifying variables and functions that
* might contain or return a password or other sensitive information.
*/
import cpp
/**
* Holds if the name `s` suggests something might contain or return a password
* or other sensitive information.
*/
bindingset[s]
private predicate suspicious(string s) {
(
@@ -16,14 +25,23 @@ private predicate suspicious(string s) {
)
}
/**
* A variable that might contain a password or other sensitive information.
*/
class SensitiveVariable extends Variable {
SensitiveVariable() { suspicious(getName().toLowerCase()) }
}
/**
* A function that might return a password or other sensitive information.
*/
class SensitiveFunction extends Function {
SensitiveFunction() { suspicious(getName().toLowerCase()) }
}
/**
* An expression whose value might be a password or other sensitive information.
*/
class SensitiveExpr extends Expr {
SensitiveExpr() {
this.(VariableAccess).getTarget() instanceof SensitiveVariable or