diff --git a/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.cpp b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.cpp new file mode 100644 index 000000000000..f96d67517b75 --- /dev/null +++ b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.cpp @@ -0,0 +1,23 @@ +char * create (int arg) { + if (arg > 42) { + // this function may return NULL + return NULL; + } + char * r = malloc(arg); + snprintf(r, arg -1, "Hello"); + return r; +} + +void process(char *str) { + // str is dereferenced + if (str[0] == 'H') { + printf("Hello H\n"); + } +} + +void test(int arg) { + // first function returns a pointer that may be NULL + char *str = create(arg); + // str is not checked for nullness before being passed to process function + process(str); +} diff --git a/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.qhelp b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.qhelp new file mode 100644 index 000000000000..6c802a9b60b3 --- /dev/null +++ b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.qhelp @@ -0,0 +1,26 @@ + + + + +

This rule finds a dereference of a function parameter, whose value comes from another function call that may return NULL, without checks in the meantime.

+
+ + +

A check should be added between the return of the function which may return NULL, and its use by the function dereferencing ths pointer.

+
+ + + + + + +
  • + + Null Dereference + +
  • +
    + +
    diff --git a/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.ql b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.ql new file mode 100644 index 000000000000..875c4f1dd966 --- /dev/null +++ b/cpp/ql/src/experimental/Likely Bugs/DerefNullResult.ql @@ -0,0 +1,34 @@ +/** + * @name Null dereference from a function result + * @description A function parameter is dereferenced, + * while it comes from a function that may return NULL, + * and is not checked for nullness by the caller. + * @kind problem + * @id cpp/deref-null-result + * @problem.severity recommendation + * @tags reliability + * security + * external/cwe/cwe-476 + */ + +import cpp +import semmle.code.cpp.dataflow.new.DataFlow + +from Function nuller, Parameter pd, FunctionCall fc, Variable v +where + mayReturnNull(nuller) and + functionDereferences(pd.getFunction(), pd.getIndex()) and + // there is a function call which will deref parameter pd + fc.getTarget() = pd.getFunction() and + // the parameter pd comes from a variable v + DataFlow::localFlow(DataFlow::exprNode(v.getAnAccess()), + DataFlow::exprNode(fc.getArgument(pd.getIndex()))) and + // this variable v was assigned by a call to the nuller function + unique( | | v.getAnAssignedValue()) = nuller.getACallToThisFunction() and + // this variable v is not accessed for an operation (check for NULLness) + not exists(VariableAccess vc | + vc.getTarget() = v and + (vc.getParent() instanceof Operation or vc.getParent() instanceof IfStmt) + ) +select fc, "This function call may deref $@ when it can be NULL from $@", v, v.getName(), nuller, + nuller.getName()