Skip to content

Commit cce39fb

Browse files
authored
Merge pull request #9998 from d10c/use-strcpyfunction-in-bad-strncpy-size
Use StrcpyFunction in `cpp/bad-strncpy-size` This PR: - Uses the [StrcpyFunction](https://github.com/github/codeql/blob/main/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll#L14) class in the [StrncpyFlippedArgs](https://github.com/github/codeql/blob/main/cpp/ql/src/Likely%20Bugs/Memory%20Management/StrncpyFlippedArgs.ql) query instead of an ad-hoc predicate for finding strcpy-like functions. - Tests this by adding one previously unsupported strcpy-like function (`wcsxfrm_l`) to StrncpyFlippedArgs's test.cpp.
2 parents b2c22da + 60f4049 commit cce39fb

File tree

4 files changed

+42
-41
lines changed

4 files changed

+42
-41
lines changed

cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.ql

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import cpp
1919
import Buffer
2020
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
21+
private import semmle.code.cpp.models.implementations.Strcpy
2122

2223
predicate isSizePlus(Expr e, BufferSizeExpr baseSize, int plus) {
2324
// baseSize
@@ -41,33 +42,6 @@ predicate isSizePlus(Expr e, BufferSizeExpr baseSize, int plus) {
4142
)
4243
}
4344

44-
predicate strncpyFunction(Function f, int argDest, int argSrc, int argLimit) {
45-
exists(string name | name = f.getName() |
46-
name =
47-
[
48-
"strcpy_s", // strcpy_s(dst, max_amount, src)
49-
"wcscpy_s", // wcscpy_s(dst, max_amount, src)
50-
"_mbscpy_s" // _mbscpy_s(dst, max_amount, src)
51-
] and
52-
argDest = 0 and
53-
argSrc = 2 and
54-
argLimit = 1
55-
or
56-
name =
57-
[
58-
"strncpy", // strncpy(dst, src, max_amount)
59-
"strncpy_l", // strncpy_l(dst, src, max_amount, locale)
60-
"wcsncpy", // wcsncpy(dst, src, max_amount)
61-
"_wcsncpy_l", // _wcsncpy_l(dst, src, max_amount, locale)
62-
"_mbsncpy", // _mbsncpy(dst, src, max_amount)
63-
"_mbsncpy_l" // _mbsncpy_l(dst, src, max_amount, locale)
64-
] and
65-
argDest = 0 and
66-
argSrc = 1 and
67-
argLimit = 2
68-
)
69-
}
70-
7145
string nthString(int num) {
7246
num = 0 and
7347
result = "first"
@@ -96,11 +70,13 @@ int arrayExprFixedSize(Expr e) {
9670
}
9771

9872
from
99-
Function f, FunctionCall fc, int argDest, int argSrc, int argLimit, int charSize, Access copyDest,
100-
Access copySource, string name, string nth
73+
StrcpyFunction f, FunctionCall fc, int argDest, int argSrc, int argLimit, int charSize,
74+
Access copyDest, Access copySource, string name, string nth
10175
where
10276
f = fc.getTarget() and
103-
strncpyFunction(f, argDest, argSrc, argLimit) and
77+
argDest = f.getParamDest() and
78+
argSrc = f.getParamSrc() and
79+
argLimit = f.getParamSize() and
10480
copyDest = fc.getArgument(argDest) and
10581
copySource = fc.getArgument(argSrc) and
10682
// Some of the functions operate on a larger char type, like `wchar_t`, so we
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `cpp/bad-strncpy-size` now covers more `strncpy`-like functions than before, including `strxfrm`(`_l`), `wcsxfrm`(`_l`), and `stpncpy`. Users of this query may see an increase in results.
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
| test.c:22:2:22:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
22
| test.c:33:2:33:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
3-
| test.cpp:19:2:19:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
4-
| test.cpp:20:2:20:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
53
| test.cpp:21:2:21:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
6-
| test.cpp:30:2:30:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
4+
| test.cpp:22:2:22:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
5+
| test.cpp:23:2:23:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
76
| test.cpp:32:2:32:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
8-
| test.cpp:33:2:33:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
97
| test.cpp:34:2:34:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
108
| test.cpp:35:2:35:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
11-
| test.cpp:45:2:45:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
12-
| test.cpp:46:2:46:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
9+
| test.cpp:36:2:36:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
10+
| test.cpp:37:2:37:8 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. |
1311
| test.cpp:47:2:47:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
14-
| test.cpp:60:3:60:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
15-
| test.cpp:63:3:63:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
16-
| test.cpp:68:2:68:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
17-
| test.cpp:79:3:79:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
18-
| test.cpp:82:3:82:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
12+
| test.cpp:48:2:48:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
13+
| test.cpp:49:2:49:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
14+
| test.cpp:62:3:62:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
15+
| test.cpp:65:3:65:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
16+
| test.cpp:70:2:70:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
17+
| test.cpp:81:3:81:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
18+
| test.cpp:84:3:84:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
19+
| test.cpp:105:2:105:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. |
20+
| test.cpp:107:2:107:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. |
21+
| test.cpp:108:2:108:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. |
22+
| test.cpp:109:2:109:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. |
23+
| test.cpp:110:2:110:10 | call to wcsxfrm_l | Potentially unsafe call to wcsxfrm_l; third argument should be size of destination. |

cpp/ql/test/query-tests/Likely Bugs/Memory Management/StrncpyFlippedArgs/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11

22
typedef unsigned int size_t;
33
typedef unsigned int errno_t;
4+
typedef void *locale_t;
45

56
char *strncpy(char *__restrict destination, const char *__restrict source, size_t num);
67
wchar_t *wcsncpy(wchar_t *__restrict destination, const wchar_t *__restrict source, size_t num);
8+
size_t wcsxfrm_l(wchar_t *ws1, const wchar_t *ws2, size_t n, locale_t locale);
79
errno_t strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource);
810

911
size_t strlen(const char *str);
@@ -93,3 +95,17 @@ void test8(char x[], char y[]) {
9395
// that it will be a false positive if we report it.
9496
strncpy(x, y, 32);
9597
}
98+
99+
void test9()
100+
{
101+
wchar_t buf1[10];
102+
wchar_t buf2[20];
103+
const wchar_t *str = L"01234567890123456789";
104+
105+
wcsxfrm_l(buf1, str, sizeof(buf1), nullptr); // BAD (but not a StrncpyFlippedArgs bug)
106+
wcsxfrm_l(buf1, str, sizeof(buf1) / sizeof(wchar_t), nullptr); // GOOD
107+
wcsxfrm_l(buf1, str, wcslen(str), nullptr); // BAD
108+
wcsxfrm_l(buf1, str, wcslen(str) + 1, nullptr); // BAD
109+
wcsxfrm_l(buf1, buf2, sizeof(buf2), nullptr); // BAD
110+
wcsxfrm_l(buf1, buf2, sizeof(buf2) / sizeof(wchar_t), nullptr); // BAD
111+
}

0 commit comments

Comments
 (0)