Skip to content

Commit edf2b54

Browse files
committed
CPP: Model strndup.
1 parent 0627fad commit edf2b54

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

cpp/ql/src/semmle/code/cpp/models/implementations/Strdup.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,32 @@ class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction
4343
output.isReturnValueDeref()
4444
}
4545
}
46+
47+
/**
48+
* A `strndup` style allocation function.
49+
*/
50+
class StrndupFunction extends AllocationFunction, ArrayFunction, TaintFunction {
51+
StrndupFunction() {
52+
exists(string name |
53+
hasGlobalOrStdName(name) and
54+
(
55+
// strndup(str, maxlen)
56+
name = "strndup"
57+
)
58+
)
59+
}
60+
61+
override predicate hasArrayInput(int bufParam) { bufParam = 0 }
62+
63+
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 }
64+
65+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
66+
// This function may do only a partial copy of the input buffer to the output
67+
// buffer, so it's a taint flow.
68+
(
69+
input.isParameterDeref(0) or
70+
input.isParameter(1)
71+
) and
72+
output.isReturnValueDeref()
73+
}
74+
}

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,13 @@
337337
| taint.cpp:370:13:370:26 | hello, world | taint.cpp:370:6:370:11 | call to strdup | TAINT |
338338
| taint.cpp:371:6:371:12 | call to strndup | taint.cpp:371:2:371:25 | ... = ... | |
339339
| taint.cpp:371:6:371:12 | call to strndup | taint.cpp:374:7:374:7 | c | |
340+
| taint.cpp:371:14:371:19 | source | taint.cpp:371:6:371:12 | call to strndup | TAINT |
341+
| taint.cpp:371:22:371:24 | 100 | taint.cpp:371:6:371:12 | call to strndup | TAINT |
340342
| taint.cpp:377:23:377:28 | source | taint.cpp:381:30:381:35 | source | |
341343
| taint.cpp:381:6:381:12 | call to strndup | taint.cpp:381:2:381:36 | ... = ... | |
342344
| taint.cpp:381:6:381:12 | call to strndup | taint.cpp:382:7:382:7 | a | |
345+
| taint.cpp:381:14:381:27 | hello, world | taint.cpp:381:6:381:12 | call to strndup | TAINT |
346+
| taint.cpp:381:30:381:35 | source | taint.cpp:381:6:381:12 | call to strndup | TAINT |
343347
| taint.cpp:385:27:385:32 | source | taint.cpp:389:13:389:18 | source | |
344348
| taint.cpp:389:6:389:11 | call to wcsdup | taint.cpp:389:2:389:19 | ... = ... | |
345349
| taint.cpp:389:6:389:11 | call to wcsdup | taint.cpp:391:7:391:7 | a | |

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,15 +371,15 @@ void test_strdup(char *source)
371371
c = strndup(source, 100);
372372
sink(a); // tainted
373373
sink(b);
374-
sink(c); // tainted [NOT DETECTED]
374+
sink(c); // tainted
375375
}
376376

377377
void test_strndup(int source)
378378
{
379379
char *a;
380380

381381
a = strndup("hello, world", source);
382-
sink(a);
382+
sink(a); // tainted
383383
}
384384

385385
void test_wcsdup(wchar_t *source)

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
| taint.cpp:351:7:351:7 | a | taint.cpp:330:6:330:11 | call to source |
3939
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
4040
| taint.cpp:372:7:372:7 | a | taint.cpp:365:24:365:29 | source |
41+
| taint.cpp:374:7:374:7 | c | taint.cpp:365:24:365:29 | source |
42+
| taint.cpp:382:7:382:7 | a | taint.cpp:377:23:377:28 | source |
4143
| taint.cpp:391:7:391:7 | a | taint.cpp:385:27:385:32 | source |
4244
| taint.cpp:423:7:423:7 | a | taint.cpp:422:14:422:19 | call to source |
4345
| taint.cpp:424:9:424:17 | call to getMember | taint.cpp:422:14:422:19 | call to source |

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
| taint.cpp:351:7:351:7 | taint.cpp:330:6:330:11 | AST only |
2626
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
2727
| taint.cpp:372:7:372:7 | taint.cpp:365:24:365:29 | AST only |
28+
| taint.cpp:374:7:374:7 | taint.cpp:365:24:365:29 | AST only |
29+
| taint.cpp:382:7:382:7 | taint.cpp:377:23:377:28 | AST only |
2830
| taint.cpp:391:7:391:7 | taint.cpp:385:27:385:32 | AST only |
2931
| taint.cpp:423:7:423:7 | taint.cpp:422:14:422:19 | AST only |
3032
| taint.cpp:424:9:424:17 | taint.cpp:422:14:422:19 | AST only |

0 commit comments

Comments
 (0)