diff --git a/cpp/ql/src/semmle/code/cpp/models/Models.qll b/cpp/ql/src/semmle/code/cpp/models/Models.qll index 1e36b6b7831..4689cb1c7c8 100644 --- a/cpp/ql/src/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/src/semmle/code/cpp/models/Models.qll @@ -1,6 +1,7 @@ private import implementations.Allocation private import implementations.Deallocation private import implementations.Fread +private import implementations.Gets private import implementations.IdentityFunction private import implementations.Inet private import implementations.Memcpy diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll new file mode 100644 index 00000000000..6b71ed5e0d4 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll @@ -0,0 +1,43 @@ +import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect + +/** + * The standard functions `gets` and `fgets`. + */ +class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction, SideEffectFunction { + GetsFunction() { + exists(string name | name = getName() | + name = "gets" or // gets(str) + name = "fgets" // fgets(str, num, stream) + ) + } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + input.isParameter(0) and + output.isReturnValue() + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isParameterDeref(2) and + output.isParameterDeref(0) + } + + override predicate parameterNeverEscapes(int index) { index = 2 } + + override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 } + + override predicate parameterIsAlwaysReturned(int index) { index = 0 } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 0 and + buffer = true and + mustWrite = true + } +} diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected index 7eadb46af45..3de16d289a0 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected @@ -10,4 +10,6 @@ | test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only | | test.cpp:87:12:87:15 | call to gets | test.cpp:87:2:87:8 | pointer | AST only | | test.cpp:87:17:87:22 | buffer | test.cpp:84:7:84:12 | buffer | AST only | +| test.cpp:87:17:87:22 | buffer | test.cpp:85:8:85:14 | pointer | IR only | +| test.cpp:87:17:87:22 | buffer | test.cpp:87:12:87:15 | call to gets | IR only | | test.cpp:87:17:87:22 | buffer | test.cpp:87:17:87:22 | array to pointer conversion | IR only | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected index 4914da71599..ef38dd33831 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected @@ -43,5 +43,7 @@ | test.cpp:87:12:87:15 | call to gets | test.cpp:85:8:85:14 | pointer | | | test.cpp:87:12:87:15 | call to gets | test.cpp:87:12:87:15 | call to gets | | | test.cpp:87:17:87:22 | buffer | test.cpp:80:18:80:18 | s | | +| test.cpp:87:17:87:22 | buffer | test.cpp:85:8:85:14 | pointer | | +| test.cpp:87:17:87:22 | buffer | test.cpp:87:12:87:15 | call to gets | | | test.cpp:87:17:87:22 | buffer | test.cpp:87:17:87:22 | array to pointer conversion | | | test.cpp:87:17:87:22 | buffer | test.cpp:87:17:87:22 | buffer | | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index 3b73052432d..2417990beb2 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -1,5 +1,7 @@ | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread | | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:26:8:26:9 | i3 | fgets | | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:13:31:17 | call to fgets | fgets | +| funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:19:31:21 | i41 | fgets | | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets | | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets | +| funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:18:41:20 | i61 | gets |