Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 16f2bac

Browse files
cpp - Using the return value of a strcpy or related string copy function in an if statement
1 parent 54493eb commit 16f2bac

8 files changed

Lines changed: 332 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313
/.vs/ql/v15/Browse.VC.db
1414
/.vs/ProjectSettings.json
1515

16+
/.vs/ql_6324/v15
17+
/.vs/VSWorkspaceState.json
18+
/.vs/slnx.sqlite-journal
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
if(strcpy(szbuf1, "Manager") == 0) // most likely strcmp was intended instead of strcpy
2+
{
3+
// ...
4+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>This rule finds uses of the string copy function calls that return the <code>destination</code> parameter,
8+
and that do not have a return value reserved to indicate an error.</p>
9+
10+
<p>The rule flags occurrences using such string copy functions as the conditional of an <code>if</code> statement, either directly, as part of an equality operator or a logical operator.</p>
11+
12+
<p>The string copy functions that the rule takes into consideration are:
13+
<li>strcpy</li>
14+
<li>wcscpy</li>
15+
<li>_mbscpy</li>
16+
<li>strncpy</li>
17+
<li>_strncpy_l</li>
18+
<li>wcsncpy</li>
19+
<li>_wcsncpy_l</li>
20+
<li>_mbsncpy</li>
21+
<li>_mbsncpy_l</li>
22+
</p>
23+
24+
<p>NOTE: It is highly recommended to consider using a more secure version of string manipulation functions suchas as <code>strcpy_s</code>.</p>
25+
26+
</overview>
27+
<recommendation>
28+
<p>Check to ensure that the flagged expressions are not typos.</p>
29+
<p>If a string comparison is intended, change the function to the appropriate string comparison function.</p>
30+
<p>If a string copy is really intended, very likely a secure version of the string copy function such as <code>strcpy_s</code> was intended instead of the insecure version of the string copy function.</p>
31+
32+
</recommendation>
33+
<example><sample src="UsingStrcpyInConditional.cpp" />
34+
</example>
35+
36+
<references>
37+
<li>Microsoft Books on Line: <a href="https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/ccf4h9w8(v=vs.110)">C6324</a></li>
38+
<li>Microsoft Books on Line: <a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=vs-2017">strcpy, wcscpy, _mbscpy</a></li>
39+
<li>US-CERT: <a href="https://www.us-cert.gov/bsi/articles/knowledge/coding-practices/strcpy_s-and-strcat_s">strncpy_s() and strncat_s()</a></li>
40+
41+
</references>
42+
</qhelp>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @name Using the return value of a strcpy or related string copy function in an if statement
3+
* @description The return value for strcpy or related string copy functions have no reserved return value to indicate an error.
4+
* Using these functions as part of an if statement condition indicates a logic error.
5+
* Either the intent was to use a more secure version of a string copy function (such as strcpy_s),
6+
* or a string compare function (such as strcmp).
7+
* @kind problem
8+
* @problem.severity error
9+
* @precision high
10+
* @id cpp/string-copy-function-in-if-condition
11+
* @tags external/microsoft/C6324
12+
*/
13+
14+
import cpp
15+
16+
predicate isStringComparisonFunction(string functionName) {
17+
functionName = "strcpy"
18+
or functionName = "wcscpy"
19+
or functionName = "_mbscpy"
20+
or functionName = "strncpy"
21+
or functionName = "_strncpy_l"
22+
or functionName = "wcsncpy"
23+
or functionName = "_wcsncpy_l"
24+
or functionName = "_mbsncpy"
25+
or functionName = "_mbsncpy_l"
26+
}
27+
28+
from IfStmt ifs,
29+
FunctionCall func
30+
where isStringComparisonFunction( func.getTarget().getQualifiedName() )
31+
and ( func = ifs.getCondition()
32+
or exists( UnaryLogicalOperation ule |
33+
ule = ifs.getCondition()
34+
and func = ule.getAChild()
35+
)
36+
or exists( BinaryLogicalOperation ble |
37+
ble = ifs.getCondition()
38+
and func = ble.getAChild()
39+
)
40+
or exists( EqualityOperation eop |
41+
eop = ifs.getCondition()
42+
and func = eop.getAChild()
43+
)
44+
)
45+
select func, "Incorrect use of function " + func.getTarget().getQualifiedName() + ". Verify the logic and replace with a secure string copy function, or a string comparison function."
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
| test.c:33:9:33:14 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
2+
| test.c:37:10:37:15 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
3+
| test.c:41:9:41:14 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
4+
| test.c:45:27:45:32 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
5+
| test.c:49:9:49:15 | call to strncpy | Incorrect use of function strncpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
6+
| test.cpp:75:9:75:14 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
7+
| test.cpp:79:10:79:15 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
8+
| test.cpp:83:9:83:14 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
9+
| test.cpp:87:27:87:32 | call to strcpy | Incorrect use of function strcpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
10+
| test.cpp:91:9:91:37 | call to wcscpy | Incorrect use of function wcscpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
11+
| test.cpp:95:9:95:14 | call to wcscpy | Incorrect use of function wcscpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
12+
| test.cpp:99:9:99:15 | call to _mbscpy | Incorrect use of function _mbscpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
13+
| test.cpp:103:9:103:15 | call to strncpy | Incorrect use of function strncpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
14+
| test.cpp:107:9:107:15 | call to wcsncpy | Incorrect use of function wcsncpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
15+
| test.cpp:111:9:111:16 | call to _mbsncpy | Incorrect use of function _mbsncpy. Verify the logic and replace with a secure string copy function, or a string comparison function. |
16+
| test.cpp:115:9:115:18 | call to _strncpy_l | Incorrect use of function _strncpy_l. Verify the logic and replace with a secure string copy function, or a string comparison function. |
17+
| test.cpp:119:9:119:18 | call to _wcsncpy_l | Incorrect use of function _wcsncpy_l. Verify the logic and replace with a secure string copy function, or a string comparison function. |
18+
| test.cpp:123:9:123:18 | call to _mbsncpy_l | Incorrect use of function _mbsncpy_l. Verify the logic and replace with a secure string copy function, or a string comparison function. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Likely Bugs/Likely Typos/UsingStrcpyInConditional.ql
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
typedef unsigned int size_t;
2+
typedef int* locale_t;
3+
4+
char* strcpy(char* destination, const char* source)
5+
{
6+
return destination;
7+
}
8+
char* strncpy(char* destination, const char* source, size_t count)
9+
{
10+
return destination;
11+
}
12+
13+
int SomeFunction()
14+
{
15+
return 1;
16+
}
17+
18+
int SomeFunctionThatTakesString(char* destination)
19+
{
20+
return 1;
21+
}
22+
23+
int strcmp(char* destination, const char* source)
24+
{
25+
return 1;
26+
}
27+
28+
void PositiveCases()
29+
{
30+
char szbuf1[100];
31+
char szbuf2[100];
32+
33+
if (strcpy(szbuf1, "test")) // Bug, direct usage
34+
{
35+
}
36+
37+
if (!strcpy(szbuf1, "test")) // Bug, unary binary operator
38+
{
39+
}
40+
41+
if (strcpy(szbuf1, "test") == 0) // Bug, equality operator
42+
{
43+
}
44+
45+
if (SomeFunction() && strcpy(szbuf1, "test")) // Bug, binary logical operator
46+
{
47+
}
48+
49+
if (strncpy(szbuf1, "test", 100)) // Bug
50+
{
51+
}
52+
}
53+
54+
void NegativeCases()
55+
{
56+
char szbuf1[100];
57+
58+
if (SomeFunction())
59+
{
60+
}
61+
62+
if (SomeFunctionThatTakesString(strcpy(szbuf1, "test")))
63+
{
64+
}
65+
66+
if (strcmp(szbuf1, "test"))
67+
{
68+
}
69+
70+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
typedef unsigned long size_t;
2+
typedef int* locale_t;
3+
4+
char* strcpy(char* destination, const char* source)
5+
{
6+
return destination;
7+
}
8+
wchar_t* wcscpy(wchar_t* destination, const wchar_t* source)
9+
{
10+
return destination;
11+
}
12+
unsigned char* _mbscpy(unsigned char* destination, const unsigned char* source)
13+
{
14+
return destination;
15+
}
16+
char* strncpy(char* destination, const char* source, size_t count)
17+
{
18+
return destination;
19+
}
20+
wchar_t* wcsncpy(wchar_t* destination, const wchar_t* source, size_t count)
21+
{
22+
return destination;
23+
}
24+
unsigned char* _mbsncpy(unsigned char* destination, const unsigned char* source, size_t count)
25+
{
26+
return destination;
27+
}
28+
char* _strncpy_l(char* destination, const char* source, size_t count, locale_t locale)
29+
{
30+
return destination;
31+
}
32+
wchar_t* _wcsncpy_l(wchar_t* destination, const wchar_t* source, size_t count, locale_t locale)
33+
{
34+
return destination;
35+
}
36+
unsigned char* _mbsncpy_l(unsigned char* destination, const unsigned char* source, size_t count, locale_t locale)
37+
{
38+
return destination;
39+
}
40+
41+
int SomeFunction()
42+
{
43+
return 1;
44+
}
45+
46+
int SomeFunctionThatTakesString(char* destination)
47+
{
48+
return 1;
49+
}
50+
51+
int strcmp(char* destination, const char* source)
52+
{
53+
return 1;
54+
}
55+
56+
int strcpy_s(char* destination, size_t dest_size, const char* source)
57+
{
58+
return 1;
59+
}
60+
61+
#define WCSCPY_6324(x,y) wcscpy(x,y)
62+
63+
void PositiveCases()
64+
{
65+
char szbuf1[100];
66+
char szbuf2[100];
67+
wchar_t wscbuf1[100];
68+
wchar_t wscbuf2[100];
69+
unsigned char mbcbuf1[100];
70+
unsigned char mbcbuf2[100];
71+
72+
locale_t x;
73+
*x = 0;
74+
75+
if (strcpy(szbuf1, "test")) // Bug, direct usage
76+
{
77+
}
78+
79+
if (!strcpy(szbuf1, "test")) // Bug, unary binary operator
80+
{
81+
}
82+
83+
if (strcpy(szbuf1, "test") == 0) // Bug, equality operator
84+
{
85+
}
86+
87+
if (SomeFunction() && strcpy(szbuf1, "test")) // Bug, binary logical operator
88+
{
89+
}
90+
91+
if (WCSCPY_6324(wscbuf1, wscbuf2)) // Bug, using a macro
92+
{
93+
}
94+
95+
if (wcscpy(wscbuf1, wscbuf2)) // Bug
96+
{
97+
}
98+
99+
if (_mbscpy(mbcbuf1, mbcbuf2)) // Bug
100+
{
101+
}
102+
103+
if (strncpy(szbuf1, "test", 100)) // Bug
104+
{
105+
}
106+
107+
if (wcsncpy(wscbuf1, wscbuf2, 100)) // Bug
108+
{
109+
}
110+
111+
if (_mbsncpy(mbcbuf1, (const unsigned char*)"test", 100)) // Bug
112+
{
113+
}
114+
115+
if (_strncpy_l(szbuf1, "test", 100, x)) // Bug
116+
{
117+
}
118+
119+
if (_wcsncpy_l(wscbuf1, wscbuf2, 100, x)) // Bug
120+
{
121+
}
122+
123+
if (_mbsncpy_l(mbcbuf1, (const unsigned char*)"test", 100, x)) //Bug
124+
{
125+
}
126+
127+
}
128+
129+
void NegativeCases()
130+
{
131+
char szbuf1[100];
132+
133+
if (SomeFunction())
134+
{
135+
}
136+
137+
if (SomeFunctionThatTakesString(strcpy(szbuf1, "test")))
138+
{
139+
}
140+
141+
if (strcmp(szbuf1, "test"))
142+
{
143+
}
144+
145+
if (strcpy_s(szbuf1, 100, "test"))
146+
{
147+
}
148+
149+
}

0 commit comments

Comments
 (0)