mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #18837 from geoffw0/overflowbuffer
C++: Improve and promote cpp/overflow-buffer
This commit is contained in:
4
cpp/ql/lib/change-notes/2025-02-20-getbuffersize.md
Normal file
4
cpp/ql/lib/change-notes/2025-02-20-getbuffersize.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue where the `getBufferSize` predicate in `commons/Buffer.qll` was returning results for references inside `offsetof` expressions, which are not accesses to a buffer.
|
||||
4
cpp/ql/lib/change-notes/2025-02-25-getbuffersize.md
Normal file
4
cpp/ql/lib/change-notes/2025-02-25-getbuffersize.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Modified the `getBufferSize` predicate in `commons/Buffer.qll` to be more tolerant in some cases involving member variables in a larger struct or class.
|
||||
@@ -71,7 +71,7 @@ private int getSize(VariableAccess va) {
|
||||
result = t.getSize()
|
||||
)
|
||||
or
|
||||
exists(Class c |
|
||||
exists(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
@@ -91,7 +91,9 @@ private int getSize(VariableAccess va) {
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
result = c.getSize() - v.(Field).getOffsetInClass(c)
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + f.getUnspecifiedType().getSize()) and
|
||||
result = trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -105,9 +107,16 @@ private int getSize(VariableAccess va) {
|
||||
private int isSource(Expr bufferExpr, Element why) {
|
||||
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
|
||||
// buffer is a fixed size array
|
||||
result = bufferVar.getUnspecifiedType().(ArrayType).getSize() and
|
||||
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
|
||||
result =
|
||||
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
|
||||
size = getSize(bufferExpr)
|
||||
|
|
||||
size
|
||||
) and
|
||||
why = bufferVar and
|
||||
not memberMayBeVarSize(_, bufferVar) and
|
||||
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and
|
||||
// zero sized arrays are likely to have special usage, for example
|
||||
// behaving a bit like a 'union' overlapping other fields.
|
||||
not result = 0
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
* buffer.
|
||||
* @kind problem
|
||||
* @id cpp/overflow-buffer
|
||||
* @problem.severity recommendation
|
||||
* @problem.severity warning
|
||||
* @security-severity 9.3
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-119
|
||||
* external/cwe/cwe-121
|
||||
|
||||
4
cpp/ql/src/change-notes/2025-02-20-overflow-buffer.md
Normal file
4
cpp/ql/src/change-notes/2025-02-20-overflow-buffer.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query "Call to memory access function may overflow buffer" (`cpp/overflow-buffer`) has been added to the security-extended query suite. The query detects a range of buffer overflow and underflow issues.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Due to changes in libraries the query "Static array access may cause overflow" (`cpp/static-buffer-overflow`) will no longer report cases where multiple fields of a struct or class are written with a single `memset` or similar operation.
|
||||
@@ -1,5 +1,3 @@
|
||||
| tests.cpp:45:9:45:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
|
||||
| tests.cpp:60:9:60:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
|
||||
| tests.cpp:171:9:171:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | destination buffer |
|
||||
| tests.cpp:172:9:172:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | array |
|
||||
| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | destination buffer |
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
| tests.cpp:45:51:45:72 | sizeof(<expr>) | Potential buffer-overflow: 'charFirst' has size 16 not 32. |
|
||||
| tests.cpp:60:52:60:74 | sizeof(<expr>) | Potential buffer-overflow: 'charFirst' has size 16 not 32. |
|
||||
|
||||
@@ -42,7 +42,7 @@ void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad()
|
||||
/* Print the initial block pointed to by structCharVoid.voidSecond */
|
||||
printLine((char *)structCharVoid.voidSecond);
|
||||
/* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */
|
||||
memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid));
|
||||
memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); // [NOT DETECTED]
|
||||
structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */
|
||||
printLine((char *)structCharVoid.charFirst);
|
||||
printLine((char *)structCharVoid.voidSecond);
|
||||
@@ -57,7 +57,7 @@ void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad()
|
||||
/* Print the initial block pointed to by structCharVoid->voidSecond */
|
||||
printLine((char *)structCharVoid->voidSecond);
|
||||
/* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */
|
||||
memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid));
|
||||
memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); // [NOT DETECTED]
|
||||
structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */
|
||||
printLine((char *)structCharVoid->charFirst);
|
||||
printLine((char *)structCharVoid->voidSecond);
|
||||
@@ -292,7 +292,7 @@ namespace CWE122_Heap_Based_Buffer_Overflow__cpp_CWE193_wchar_t_ncpy_01
|
||||
delete [] data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void goodG2B()
|
||||
{
|
||||
wchar_t * data;
|
||||
@@ -459,7 +459,7 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_ncpy_01_bad()
|
||||
#ifdef _WIN32
|
||||
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format, ...);
|
||||
#define SNPRINTF _snwprintf
|
||||
#else
|
||||
#else
|
||||
int snprintf(char *s, size_t n, const char *format, ...);
|
||||
int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
|
||||
//#define SNPRINTF snprintf --- original code; using snprintf appears to be a mistake in samate?
|
||||
@@ -485,14 +485,14 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_01_bad()
|
||||
}
|
||||
|
||||
/* classes used in some test cases as a custom type */
|
||||
class TwoIntsClass
|
||||
class TwoIntsClass
|
||||
{
|
||||
public: // Needed to access variables from label files
|
||||
int intOne;
|
||||
int intTwo;
|
||||
};
|
||||
|
||||
class OneIntClass
|
||||
class OneIntClass
|
||||
{
|
||||
public: // Needed to access variables from label files
|
||||
int intOne;
|
||||
@@ -636,7 +636,7 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_31_bad()
|
||||
|
||||
int rand(void);
|
||||
|
||||
int globalReturnsTrueOrFalse()
|
||||
int globalReturnsTrueOrFalse()
|
||||
{
|
||||
return (rand() % 2);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
| tests.cpp:1055:2:1055:8 | call to strncpy | This 'call to strncpy' operation is limited to 131 bytes but the destination is only 128 bytes. |
|
||||
| tests.cpp:1057:2:1057:8 | call to strncpy | This 'call to strncpy' operation is limited to 131 bytes but the destination is only 64 bytes. |
|
||||
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'call to strncpy' operation is limited to 1025 bytes but the destination is only 1024 bytes. |
|
||||
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'call to strncpy' operation is limited to 129 bytes but the destination is only 128 bytes. |
|
||||
|
||||
@@ -17,69 +17,81 @@
|
||||
| tests.cpp:285:3:285:8 | call to memset | This 'memset' operation accesses 128 bytes but the $@ is only 64 bytes. | tests.cpp:283:12:283:23 | new[] | destination buffer |
|
||||
| tests.cpp:292:3:292:8 | call to memset | This 'memset' operation accesses 11 bytes but the $@ is only 10 bytes. | tests.cpp:289:8:289:12 | array | destination buffer |
|
||||
| tests.cpp:310:2:310:7 | call to memset | This 'memset' operation accesses 21 bytes but the $@ is only 20 bytes. | tests.cpp:301:10:301:14 | myVar | destination buffer |
|
||||
| tests.cpp:312:2:312:7 | call to memset | This 'memset' operation accesses 17 bytes but the $@ is only 16 bytes. | tests.cpp:298:7:298:12 | buffer | destination buffer |
|
||||
| tests.cpp:314:2:314:7 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:299:6:299:10 | field | destination buffer |
|
||||
| tests.cpp:346:2:346:14 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:349:2:349:14 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:350:17:350:29 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:352:2:352:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:355:2:355:13 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:356:16:356:27 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:358:2:358:16 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:361:2:361:16 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:362:25:362:39 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:365:23:365:34 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:373:3:373:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 100 bytes. | tests.cpp:368:47:368:52 | call to malloc | array |
|
||||
| tests.cpp:376:3:376:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 101 bytes. | tests.cpp:369:47:369:52 | call to malloc | array |
|
||||
| tests.cpp:446:3:446:24 | access to array | This array indexing operation accesses a negative index -3 on the $@. | tests.cpp:444:7:444:14 | intArray | array |
|
||||
| tests.cpp:454:3:454:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:456:3:456:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:459:3:459:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:461:3:461:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:476:2:476:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:477:2:477:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:481:2:481:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:487:2:487:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:473:21:473:26 | call to malloc | array |
|
||||
| tests.cpp:491:2:491:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:474:21:474:26 | call to malloc | array |
|
||||
| tests.cpp:519:3:519:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:502:15:502:20 | call to malloc | destination buffer |
|
||||
| tests.cpp:519:3:519:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:510:16:510:21 | call to malloc | destination buffer |
|
||||
| tests.cpp:541:6:541:10 | call to fread | This 'fread' operation may access 101 bytes but the $@ is only 100 bytes. | tests.cpp:532:7:532:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:546:6:546:10 | call to fread | This 'fread' operation may access 400 bytes but the $@ is only 100 bytes. | tests.cpp:532:7:532:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:569:6:569:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:565:7:565:12 | buffer | array |
|
||||
| tests.cpp:577:7:577:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:565:7:565:12 | buffer | array |
|
||||
| tests.cpp:637:6:637:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
|
||||
| tests.cpp:645:7:645:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
|
||||
| tests.cpp:708:3:708:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:712:3:712:8 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:716:3:716:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 16 bytes. | tests.cpp:692:16:692:16 | b | destination buffer |
|
||||
| tests.cpp:727:2:727:7 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:753:5:753:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
|
||||
| tests.cpp:756:5:756:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
|
||||
| tests.cpp:760:5:760:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:761:5:761:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:763:5:763:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:764:5:764:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:774:5:774:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
|
||||
| tests.cpp:777:5:777:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
|
||||
| tests.cpp:795:5:795:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:790:16:790:16 | b | destination buffer |
|
||||
| tests.cpp:822:5:822:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:825:5:825:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:827:5:827:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:830:5:830:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:831:5:831:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:833:5:833:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:835:5:835:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:846:5:846:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:847:5:847:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:848:5:848:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:849:5:849:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:851:5:851:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:862:5:862:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:863:5:863:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:864:5:864:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:865:5:865:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:866:5:866:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:867:5:867:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:348:2:348:14 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:351:2:351:14 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:352:17:352:29 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:354:2:354:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:357:2:357:13 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:358:16:358:27 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:360:2:360:16 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:363:2:363:16 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:364:25:364:39 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:367:23:367:34 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:369:2:369:13 | access to array | This array indexing operation accesses a negative index -2 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:370:2:370:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:374:2:374:13 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:394:3:394:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 100 bytes. | tests.cpp:389:47:389:52 | call to malloc | array |
|
||||
| tests.cpp:397:3:397:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 101 bytes. | tests.cpp:390:47:390:52 | call to malloc | array |
|
||||
| tests.cpp:467:3:467:24 | access to array | This array indexing operation accesses a negative index -3 on the $@. | tests.cpp:465:7:465:14 | intArray | array |
|
||||
| tests.cpp:475:3:475:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:477:3:477:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:480:3:480:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:482:3:482:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:497:2:497:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:498:2:498:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:502:2:502:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:508:2:508:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:494:21:494:26 | call to malloc | array |
|
||||
| tests.cpp:512:2:512:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:495:21:495:26 | call to malloc | array |
|
||||
| tests.cpp:540:3:540:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:523:15:523:20 | call to malloc | destination buffer |
|
||||
| tests.cpp:540:3:540:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:531:16:531:21 | call to malloc | destination buffer |
|
||||
| tests.cpp:562:6:562:10 | call to fread | This 'fread' operation may access 101 bytes but the $@ is only 100 bytes. | tests.cpp:553:7:553:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:567:6:567:10 | call to fread | This 'fread' operation may access 400 bytes but the $@ is only 100 bytes. | tests.cpp:553:7:553:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:590:6:590:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:586:7:586:12 | buffer | array |
|
||||
| tests.cpp:598:7:598:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:586:7:586:12 | buffer | array |
|
||||
| tests.cpp:658:6:658:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:654:7:654:12 | buffer | array |
|
||||
| tests.cpp:666:7:666:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:654:7:654:12 | buffer | array |
|
||||
| tests.cpp:729:3:729:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:733:3:733:8 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:737:3:737:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 16 bytes. | tests.cpp:713:16:713:16 | b | destination buffer |
|
||||
| tests.cpp:748:2:748:7 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:774:5:774:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:756:20:756:22 | b_1 | destination buffer |
|
||||
| tests.cpp:777:5:777:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:756:20:756:22 | b_1 | destination buffer |
|
||||
| tests.cpp:781:5:781:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:782:5:782:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:784:5:784:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:785:5:785:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:795:5:795:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:761:20:761:22 | b_2 | destination buffer |
|
||||
| tests.cpp:798:5:798:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:761:20:761:22 | b_2 | destination buffer |
|
||||
| tests.cpp:816:5:816:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:811:16:811:16 | b | destination buffer |
|
||||
| tests.cpp:843:5:843:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:846:5:846:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:848:5:848:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:851:5:851:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:852:5:852:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:854:5:854:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:856:5:856:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:867:5:867:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:868:5:868:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:869:5:869:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:870:5:870:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:872:5:872:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:883:5:883:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:884:5:884:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:885:5:885:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:886:5:886:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:887:5:887:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:888:5:888:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:984:2:984:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:989:2:989:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:994:2:994:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1001:2:1001:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1009:2:1009:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1031:2:1031:7 | call to memset | This 'memset' operation accesses 130 bytes but the $@ is only 120 bytes. | tests.cpp:1020:12:1020:15 | arr1 | destination buffer |
|
||||
| tests.cpp:1050:2:1050:7 | call to memset | This 'memset' operation accesses 132 bytes but the $@ is only 128 bytes. | tests.cpp:1037:8:1037:14 | buffer1 | destination buffer |
|
||||
| tests.cpp:1052:2:1052:7 | call to memset | This 'memset' operation accesses 132 bytes but the $@ is only 64 bytes. | tests.cpp:1041:8:1041:14 | buffer2 | destination buffer |
|
||||
| tests.cpp:1055:2:1055:8 | call to strncpy | This 'strncpy' operation may access 131 bytes but the $@ is only 128 bytes. | tests.cpp:1037:8:1037:14 | buffer1 | destination buffer |
|
||||
| tests.cpp:1057:2:1057:8 | call to strncpy | This 'strncpy' operation may access 131 bytes but the $@ is only 64 bytes. | tests.cpp:1041:8:1041:14 | buffer2 | destination buffer |
|
||||
| tests_restrict.c:12:2:12:7 | call to memcpy | This 'memcpy' operation accesses 2 bytes but the $@ is only 1 byte. | tests_restrict.c:7:6:7:13 | smallbuf | source buffer |
|
||||
| unions.cpp:26:2:26:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:21:10:21:11 | mu | destination buffer |
|
||||
| unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer |
|
||||
@@ -88,5 +100,4 @@
|
||||
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'strncpy' operation may access 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
|
||||
| var_size_struct.cpp:87:3:87:19 | access to array | This array indexing operation accesses byte offset 67 but the $@ is only 64 bytes. | var_size_struct.cpp:78:7:78:14 | elements | array |
|
||||
| var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
| var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
| tests.cpp:163:3:163:11 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
|
||||
| tests.cpp:164:8:164:16 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
|
||||
| tests.cpp:245:42:245:42 | 6 | Potential buffer-overflow: 'global_array_5' has size 5 not 6. |
|
||||
| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:351:2:351:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:352:17:352:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:1055:26:1055:39 | ... - ... | Potential buffer-overflow: 'buffer1' has size 128 not 131. |
|
||||
| tests.cpp:1057:26:1057:39 | ... - ... | Potential buffer-overflow: 'buffer2' has size 64 not 131. |
|
||||
| var_size_struct.cpp:103:39:103:41 | 129 | Potential buffer-overflow: 'str' has size 128 not 129. |
|
||||
|
||||
@@ -27,26 +27,26 @@ edges
|
||||
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
|
||||
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | |
|
||||
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | **argv | tests.cpp:872:32:872:35 | **argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | *argv | tests.cpp:872:32:872:35 | *argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | **argv | tests.cpp:1060:32:1060:35 | **argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | *argv | tests.cpp:1060:32:1060:35 | *argv | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | |
|
||||
| tests.cpp:613:19:613:24 | *source | tests.cpp:615:17:615:22 | *source | provenance | |
|
||||
| tests.cpp:622:19:622:24 | *source | tests.cpp:625:2:625:16 | *... = ... | provenance | |
|
||||
| tests.cpp:625:2:625:2 | *s [post update] [*home] | tests.cpp:628:14:628:14 | *s [*home] | provenance | |
|
||||
| tests.cpp:625:2:625:16 | *... = ... | tests.cpp:625:2:625:2 | *s [post update] [*home] | provenance | |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:14:628:19 | *home | provenance | |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:16:628:19 | *home | provenance | |
|
||||
| tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home | provenance | |
|
||||
| tests.cpp:872:32:872:35 | **argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | **argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | *argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | *argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
|
||||
| tests.cpp:897:9:897:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | |
|
||||
| tests.cpp:898:9:898:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | |
|
||||
| tests.cpp:634:19:634:24 | *source | tests.cpp:636:17:636:22 | *source | provenance | |
|
||||
| tests.cpp:643:19:643:24 | *source | tests.cpp:646:2:646:16 | *... = ... | provenance | |
|
||||
| tests.cpp:646:2:646:2 | *s [post update] [*home] | tests.cpp:649:14:649:14 | *s [*home] | provenance | |
|
||||
| tests.cpp:646:2:646:16 | *... = ... | tests.cpp:646:2:646:2 | *s [post update] [*home] | provenance | |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:14:649:19 | *home | provenance | |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:16:649:19 | *home | provenance | |
|
||||
| tests.cpp:649:16:649:19 | *home | tests.cpp:649:14:649:19 | *home | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
|
||||
| tests.cpp:1085:9:1085:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | |
|
||||
| tests.cpp:1086:9:1086:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | |
|
||||
| tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
|
||||
nodes
|
||||
@@ -72,18 +72,18 @@ nodes
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:613:19:613:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:615:17:615:22 | *source | semmle.label | *source |
|
||||
| tests.cpp:622:19:622:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:625:2:625:2 | *s [post update] [*home] | semmle.label | *s [post update] [*home] |
|
||||
| tests.cpp:625:2:625:16 | *... = ... | semmle.label | *... = ... |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | semmle.label | *s [*home] |
|
||||
| tests.cpp:628:14:628:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:628:16:628:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:872:32:872:35 | **argv | semmle.label | **argv |
|
||||
| tests.cpp:872:32:872:35 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:897:9:897:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:898:9:898:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:634:19:634:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:636:17:636:22 | *source | semmle.label | *source |
|
||||
| tests.cpp:643:19:643:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:646:2:646:2 | *s [post update] [*home] | semmle.label | *s [post update] [*home] |
|
||||
| tests.cpp:646:2:646:16 | *... = ... | semmle.label | *... = ... |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | semmle.label | *s [*home] |
|
||||
| tests.cpp:649:14:649:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:649:16:649:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | semmle.label | **argv |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:1085:9:1085:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:1086:9:1086:15 | *access to array | semmle.label | *access to array |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv |
|
||||
@@ -97,5 +97,5 @@ subpaths
|
||||
| main.cpp:9:29:9:32 | **argv | tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | main.cpp:9:29:9:32 | tests_restrict_main output argument |
|
||||
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | main.cpp:9:29:9:32 | tests_restrict_main output argument |
|
||||
#select
|
||||
| tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:615:17:615:22 | *source | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:628:14:628:19 | *home | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:636:2:636:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:636:17:636:22 | *source | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:649:2:649:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:649:14:649:19 | *home | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
|
||||
@@ -18,7 +18,7 @@ void test1()
|
||||
{
|
||||
char smallbuffer[10];
|
||||
char bigbuffer[20];
|
||||
|
||||
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(smallbuffer)); // GOOD
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(bigbuffer)); // BAD: over-read
|
||||
memcpy(smallbuffer, bigbuffer, sizeof(smallbuffer)); // GOOD
|
||||
@@ -29,7 +29,7 @@ void test2()
|
||||
{
|
||||
char *smallbuffer = (char *)malloc(sizeof(char) * 10);
|
||||
char *bigbuffer = (char *)malloc(sizeof(char) * 20);
|
||||
|
||||
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(smallbuffer)); // GOOD
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(bigbuffer)); // BAD: over-read [NOT DETECTED]
|
||||
memcpy(smallbuffer, bigbuffer, sizeof(smallbuffer)); // GOOD
|
||||
@@ -59,7 +59,7 @@ void test4(int unbounded)
|
||||
{
|
||||
int bounded = 100;
|
||||
char buffer1[100], buffer2[100];
|
||||
|
||||
|
||||
memmove(buffer1, buffer2, bounded); // GOOD
|
||||
memmove(buffer1, buffer2, unbounded); // BAD: may over-write [NOT DETECTED]
|
||||
}
|
||||
@@ -107,11 +107,11 @@ void test6(bool cond)
|
||||
a = -1;
|
||||
buffer[a] = 'x'; // BAD: under-write [NOT DETECTED]
|
||||
ch = buffer[a]; // BAD: under-read [NOT DETECTED]
|
||||
|
||||
|
||||
b = 0;
|
||||
buffer[b] = 'x'; // GOOD
|
||||
ch = buffer[b]; // GOOD
|
||||
|
||||
|
||||
c = 100;
|
||||
buffer[c] = 'x'; // BAD: over-write [NOT DETECTED]
|
||||
ch = buffer[c]; // BAD: over-read [NOT DETECTED]
|
||||
@@ -120,7 +120,7 @@ void test6(bool cond)
|
||||
d = 1000;
|
||||
buffer[d] = 'x'; // BAD: over-write [NOT DETECTED]
|
||||
ch = buffer[d]; // BAD: over-read [NOT DETECTED]
|
||||
|
||||
|
||||
e = 1000;
|
||||
e = 0;
|
||||
buffer[e] = 'x'; // GOOD
|
||||
@@ -130,12 +130,12 @@ void test6(bool cond)
|
||||
if (cond) {f = 1000;}
|
||||
buffer[f] = 'x'; // BAD: may over-write [NOT DETECTED]
|
||||
ch = buffer[f]; // BAD: may over-read [NOT DETECTED]
|
||||
|
||||
|
||||
g = 1000;
|
||||
if (cond) {g = 0;}
|
||||
buffer[g] = 'x'; // BAD: may over-write [NOT DETECTED]
|
||||
ch = buffer[g]; // BAD: may over-read [NOT DETECTED]
|
||||
|
||||
|
||||
h = 1000;
|
||||
if (cond)
|
||||
{
|
||||
@@ -151,13 +151,13 @@ void test6(bool cond)
|
||||
buffer[i] = 'x'; // GOOD
|
||||
ch = buffer[i]; // GOOD
|
||||
}
|
||||
|
||||
|
||||
for (j = -1; j < 100; j++)
|
||||
{
|
||||
buffer[j] = 'x'; // BAD: under-write [NOT DETECTED]
|
||||
ch = buffer[j]; // BAD: under-read [NOT DETECTED]
|
||||
}
|
||||
|
||||
|
||||
for (k = 0; k <= 100; k++)
|
||||
{
|
||||
buffer[k] = 'x'; // BAD: over-write
|
||||
@@ -187,7 +187,7 @@ void test8(int unbounded)
|
||||
{
|
||||
buffer[i] = 0; // GOOD
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < v2; i++)
|
||||
{
|
||||
buffer[i] = 0; // BAD: over-write [NOT DETECTED]
|
||||
@@ -226,7 +226,7 @@ void test9(int param)
|
||||
memset(buffer3, 0, 33); // BAD: overrun write of buffer3
|
||||
memset(buffer4, 0, 32); // GOOD
|
||||
memset(buffer4, 0, 33); // BAD: overrun write of buffer4 (buffer3)
|
||||
|
||||
|
||||
memcmp(buffer1, buffer2, 32); // GOOD
|
||||
memcmp(buffer1, buffer2, 33); // BAD: overrun read of buffer1, buffer2
|
||||
}
|
||||
@@ -274,7 +274,7 @@ void test11()
|
||||
memset(string, 0, 14); // GOOD
|
||||
memset(string, 0, 15); // BAD: overrun write of string
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
char *buffer = new char[128];
|
||||
|
||||
@@ -284,7 +284,7 @@ void test11()
|
||||
|
||||
memset(buffer, 0, 128); // BAD: overrun write of buffer
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
char array[10] = "123";
|
||||
|
||||
@@ -309,7 +309,7 @@ void test12()
|
||||
memset(&myVar, 0, sizeof(myVar)); // GOOD
|
||||
memset(&myVar, 0, sizeof(myVar) + 1); // BAD: overrun write of myVar
|
||||
memset(myVar.buffer, 0, 16); // GOOD
|
||||
memset(myVar.buffer, 0, 17); // BAD: overrun write of myVar.buffer
|
||||
memset(myVar.buffer, 0, 17); // DUBIOUS: overrun write of myVar.buffer, but not out of myVar itself [NOT DETECTED]
|
||||
memset(&(myVar.field), 0, sizeof(int)); // GOOD
|
||||
memset(&(myVar.field), 0, sizeof(int) * 2); // BAD: overrun write of myVar.field
|
||||
|
||||
@@ -317,7 +317,7 @@ void test12()
|
||||
memset(buf + 8, 0, 9); // BAD: overrun write of buf [NOT DETECTED]
|
||||
memset(dbuf + 8, 0, 8); // GOOD
|
||||
memset(dbuf + 8, 0, 9); // BAD: overrun write of dbuf [NOT DETECTED]
|
||||
|
||||
|
||||
{
|
||||
myStruct *myPtr1 = &myVar;
|
||||
myStruct *myPtr2;
|
||||
@@ -331,17 +331,19 @@ void test12()
|
||||
|
||||
{
|
||||
void *myPtr3 = (void *)(&myVar);
|
||||
|
||||
|
||||
memset(myPtr3, 0, sizeof(myStruct)); // GOOD
|
||||
memset(myPtr3, 0, sizeof(myStruct) + 1); // BAD: overrun write of myVar
|
||||
}
|
||||
}
|
||||
|
||||
void test13()
|
||||
void test13(char *argArray)
|
||||
{
|
||||
char charArray[10];
|
||||
int intArray[10];
|
||||
myStruct structArray[10];
|
||||
char *ptrArray = charArray;
|
||||
char *ptrArrayOffset = charArray + 1;
|
||||
|
||||
charArray[-1] = 1; // BAD: underrun write
|
||||
charArray[0] = 1; // GOOD
|
||||
@@ -363,7 +365,26 @@ void test13()
|
||||
|
||||
charArray[9] = (char)intArray[9]; // GOOD
|
||||
charArray[9] = (char)intArray[10]; // BAD: overrun read
|
||||
|
||||
|
||||
ptrArray[-2] = 1; // BAD: underrun write
|
||||
ptrArray[-1] = 1; // BAD: underrun write
|
||||
ptrArray[0] = 1; // GOOD
|
||||
ptrArray[8] = 1; // GOOD
|
||||
ptrArray[9] = 1; // GOOD
|
||||
ptrArray[10] = 1; // BAD: overrun write
|
||||
|
||||
ptrArrayOffset[-2] = 1; // BAD: underrun write [NOT DETECTED]
|
||||
ptrArrayOffset[-1] = 1; // GOOD (there is room for this)
|
||||
ptrArrayOffset[0] = 1; // GOOD
|
||||
ptrArrayOffset[8] = 1; // GOOD
|
||||
ptrArrayOffset[9] = 1; // BAD: overrun write [NOT DETECTED]
|
||||
ptrArrayOffset[10] = 1; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
argArray[-1] = 1; // BAD: underrun write [NOT DETECTED]
|
||||
argArray[0] = 1; // GOOD
|
||||
argArray[1] = 1; // GOOD (we can't tell the length of this array)
|
||||
argArray[999] = 1; // GOOD (we can't tell the length of this array)
|
||||
|
||||
{
|
||||
unsigned short *buffer1 = (unsigned short *)malloc(sizeof(short) * 50);
|
||||
unsigned short *buffer2 = (unsigned short *)malloc(101); // 50.5 shorts
|
||||
@@ -442,13 +463,13 @@ void test17(long long *longArray)
|
||||
|
||||
{
|
||||
int intArray[5];
|
||||
|
||||
|
||||
((char *)intArray)[-3] = 0; // BAD: underrun write
|
||||
}
|
||||
|
||||
{
|
||||
int multi[10][10];
|
||||
|
||||
|
||||
multi[5][5] = 0; // GOOD
|
||||
|
||||
multi[-5][5] = 0; // BAD: underrun write [INCORRECT MESSAGE]
|
||||
@@ -511,7 +532,7 @@ void test19(bool b)
|
||||
p2 = (char *)malloc(20);
|
||||
p3 = (char *)malloc(20);
|
||||
}
|
||||
|
||||
|
||||
// ...
|
||||
|
||||
if (b)
|
||||
@@ -663,7 +684,7 @@ void test27(){
|
||||
char buffer[MAX_SIZE];
|
||||
|
||||
strncpy(dest, src, 8); // GOOD, strncpy will not read past null terminator of source
|
||||
|
||||
|
||||
if(IND < MAX_SIZE){
|
||||
buffer[IND] = 0; // GOOD: out of bounds, but inaccessible code
|
||||
}
|
||||
@@ -739,7 +760,7 @@ struct AnonUnionInStruct
|
||||
unsigned int a_2;
|
||||
unsigned int b_2;
|
||||
};
|
||||
};
|
||||
};
|
||||
unsigned int d;
|
||||
|
||||
void test37() {
|
||||
@@ -869,6 +890,173 @@ struct S2 {
|
||||
}
|
||||
};
|
||||
|
||||
typedef int MyArray[10];
|
||||
|
||||
typedef struct _MyArrayArray {
|
||||
struct {
|
||||
int as[10];
|
||||
} bs[10];
|
||||
|
||||
union {
|
||||
int i;
|
||||
char cs[4];
|
||||
} ds[10];
|
||||
|
||||
struct {
|
||||
MyArray xs;
|
||||
} ys[10];
|
||||
} MyArrayArray;
|
||||
|
||||
void test26() {
|
||||
MyArrayArray maa;
|
||||
|
||||
maa.bs[0].as[-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
maa.bs[0].as[0] = 0; // GOOD
|
||||
maa.bs[0].as[99] = 0; // GOOD (overflows into bs[9])
|
||||
maa.bs[0].as[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.bs[1].as[-1] = 0; // GOOD (underflows into bs[0])
|
||||
maa.bs[1].as[0] = 0; // GOOD
|
||||
maa.bs[1].as[99] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.bs[1].as[100] = 0; // BAD: overrun write[ NOT DETECTED]
|
||||
|
||||
maa.ds[0].i = 0; // GOOD
|
||||
maa.ds[9].i = 0; // GOOD
|
||||
maa.ds[10].i = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ds[0].cs[0] = 0; // GOOD
|
||||
maa.ds[0].cs[3] = 0; // GOOD
|
||||
maa.ds[0].cs[4] = 0; // GOOD (overflows into vs[1])
|
||||
maa.ds[0].cs[39] = 0; // GOOD (overflows into vs[9])
|
||||
maa.ds[0].cs[40] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ds[9].cs[0] = 0; // GOOD
|
||||
maa.ds[9].cs[3] = 0; // GOOD
|
||||
maa.ds[9].cs[4] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
maa.ys[0].xs[-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
maa.ys[0].xs[0] = 0; // GOOD
|
||||
maa.ys[0].xs[99] = 0; // GOOD (overflows into bs[9])
|
||||
maa.ys[0].xs[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ys[1].xs[-1] = 0; // GOOD (underflows into ys[0])
|
||||
maa.ys[1].xs[0] = 0; // GOOD
|
||||
maa.ys[1].xs[99] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ys[1].xs[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
char zs[2][2];
|
||||
zs[0][-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
zs[0][0] = 0; // GOOD
|
||||
zs[0][1] = 0; // GOOD
|
||||
zs[0][2] = 0; // GOOD
|
||||
zs[0][3] = 0; // GOOD
|
||||
zs[0][4] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
zs[1][-3] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
zs[1][-2] = 0; // GOOD
|
||||
zs[1][-1] = 0; // GOOD
|
||||
zs[1][0] = 0; // GOOD
|
||||
zs[1][1] = 0; // GOOD
|
||||
zs[1][2] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
}
|
||||
|
||||
struct Array10 {
|
||||
int values[10];
|
||||
};
|
||||
|
||||
void test27(size_t s) {
|
||||
Array10 arr;
|
||||
|
||||
if (s < sizeof(arr.values[10])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
|
||||
if (s < offsetof(Array10, values[10])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
|
||||
if (s < &(arr.values[10]) - &(arr.values[0])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
bool cond();
|
||||
|
||||
void test28() {
|
||||
int arr[10];
|
||||
|
||||
int *ptr1 = arr;
|
||||
ptr1[-1] = 0; // BAD: underrun write
|
||||
ptr1++;
|
||||
ptr1[-1] = 0; // GOOD
|
||||
|
||||
int *ptr2 = arr;
|
||||
ptr2[-1] = 0; // BAD: underrun write
|
||||
*ptr2++;
|
||||
ptr2[-1] = 0; // GOOD
|
||||
|
||||
int *ptr3 = arr;
|
||||
ptr3[-1] = 0; // BAD: underrun write
|
||||
if (cond()) {
|
||||
ptr3++;
|
||||
}
|
||||
ptr3[-1] = 0; // GOOD (depending what cond() does)
|
||||
|
||||
int *ptr4 = arr;
|
||||
ptr4[-1] = 0; // BAD: underrun write
|
||||
while (true) {
|
||||
ptr4++;
|
||||
if (cond()) break;
|
||||
}
|
||||
ptr4[-1] = 0; // GOOD
|
||||
|
||||
int *ptr5 = arr;
|
||||
ptr5[-1] = 0; // BAD: underrun write
|
||||
while (true) {
|
||||
if (cond()) ptr5++;
|
||||
if (cond()) break;
|
||||
}
|
||||
ptr5[-1] = 0; // GOOD (depending what cond() does)
|
||||
}
|
||||
|
||||
typedef int myInt29;
|
||||
typedef myInt29 myArray29[10];
|
||||
struct _myStruct29 {
|
||||
myArray29 arr1;
|
||||
myInt29 arr2[20];
|
||||
};
|
||||
typedef _myStruct29 myStruct29;
|
||||
|
||||
void test29() {
|
||||
myStruct29 *ptr;
|
||||
|
||||
memset(ptr->arr1, 0, sizeof(ptr->arr1) + sizeof(ptr->arr2)); // GOOD (overwrites arr1, arr2)
|
||||
memset(&(ptr->arr1[0]), 0, sizeof(ptr->arr1) + sizeof(ptr->arr2)); // GOOD (overwrites arr1, arr2)
|
||||
|
||||
memset(ptr->arr1, 0, sizeof(ptr->arr1) + sizeof(ptr->arr2) + 10); // BAD
|
||||
}
|
||||
|
||||
struct UnionStruct {
|
||||
int a;
|
||||
union {
|
||||
char buffer1[64];
|
||||
int b;
|
||||
};
|
||||
union {
|
||||
char buffer2[64];
|
||||
int c;
|
||||
};
|
||||
};
|
||||
|
||||
void test30() {
|
||||
UnionStruct us;
|
||||
|
||||
memset(us.buffer1, 0, sizeof(us.buffer1)); // GOOD
|
||||
memset(us.buffer1, 0, sizeof(us)); // BAD
|
||||
memset(us.buffer2, 0, sizeof(us.buffer2)); // GOOD
|
||||
memset(us.buffer2, 0, sizeof(us)); // BAD
|
||||
|
||||
strncpy(us.buffer1, "", sizeof(us.buffer1) - 1); // GOOD
|
||||
strncpy(us.buffer1, "", sizeof(us) - 1); // BAD
|
||||
strncpy(us.buffer2, "", sizeof(us.buffer2) - 1); // GOOD
|
||||
strncpy(us.buffer2, "", sizeof(us) - 1); // BAD
|
||||
}
|
||||
|
||||
int tests_main(int argc, char *argv[])
|
||||
{
|
||||
long long arr17[19];
|
||||
@@ -896,6 +1084,11 @@ int tests_main(int argc, char *argv[])
|
||||
test23();
|
||||
test24(argv[0]);
|
||||
test25(argv[0]);
|
||||
test26();
|
||||
test27(argc);
|
||||
test28();
|
||||
test29();
|
||||
test30();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ void testNotVarStruct1() {
|
||||
notVarStruct1 *nvs1 = (notVarStruct1 *)malloc(sizeof(notVarStruct1) * 2);
|
||||
|
||||
memset(nvs1->str, 0, 128); // GOOD
|
||||
memset(nvs1->str, 0, 129); // BAD: buffer overflow
|
||||
memset(nvs1->str, 0, 129); // DUBIOUS: buffer overflow (overflows nvs1->str but not nvs1 overall)
|
||||
memset(nvs1[1].str, 0, 128); // GOOD
|
||||
memset(nvs1[1].str, 0, 129); // BAD: buffer overflow
|
||||
memset(nvs1[1].str, 0, 129); // BAD: buffer overflow [NOT DETECTED]
|
||||
strncpy(nvs1->str, "Hello, world!", 128); // GOOD
|
||||
strncpy(nvs1->str, "Hello, world!", 129); // BAD
|
||||
}
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:186:3:186:9 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 2 bytes. |
|
||||
| tests.c:189:3:189:9 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
|
||||
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes. |
|
||||
| varbuffer.c:15:5:15:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:16:5:16:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:23:5:23:10 | call to strcpy | This 'call to strcpy' operation requires 12 bytes but the destination is only 11 bytes. |
|
||||
| varbuffer.c:24:5:24:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |
|
||||
| varbuffer.c:39:5:39:10 | call to strcpy | This 'call to strcpy' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:40:5:40:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:45:5:45:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:46:5:46:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:60:5:60:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:61:5:61:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:67:5:67:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Further test cases for CWE-120.
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
typedef struct _MyVarStruct {
|
||||
size_t len;
|
||||
char buffer[1]; // variable size buffer
|
||||
} MyVarStruct;
|
||||
|
||||
void testMyVarStruct()
|
||||
{
|
||||
MyVarStruct *ptr1 = (MyVarStruct*)malloc(sizeof(MyVarStruct));
|
||||
ptr1->len = 0;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // BAD: length 2, but destination only has length 1
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 1
|
||||
// ...
|
||||
|
||||
MyVarStruct *ptr2 = (MyVarStruct*)malloc(sizeof(MyVarStruct) + (sizeof(char) * 10));
|
||||
ptr2->len = 10;
|
||||
strcpy(ptr2->buffer, "123456789"); // GOOD
|
||||
strcpy(ptr2->buffer, "1234567890"); // GOOD
|
||||
strcpy(ptr2->buffer, "1234567890a"); // BAD: length 12, but destination only has length 11
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 11
|
||||
// ...
|
||||
}
|
||||
|
||||
typedef struct MyFixedStruct1 {
|
||||
int len;
|
||||
char buffer[2]; // assumed to be a fixed size buffer
|
||||
} MyFixedStruct1;
|
||||
|
||||
void testMyFixedStruct()
|
||||
{
|
||||
MyFixedStruct1 *ptr1 = (MyFixedStruct1 *)malloc(sizeof(MyFixedStruct1));
|
||||
ptr1->len = 1;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // GOOD
|
||||
strcpy(ptr1->buffer, "12"); // BAD: length 3, but destination only has length 2
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 2
|
||||
// ...
|
||||
|
||||
MyFixedStruct1 *ptr2 = (MyFixedStruct1*)malloc(sizeof(MyFixedStruct1) + (sizeof(char) * 10));
|
||||
ptr2->len = 11;
|
||||
strcpy(ptr2->buffer, "123456789"); // BAD / DUBIOUS: length 10, but destination only has length 2
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 2
|
||||
// ...
|
||||
}
|
||||
|
||||
typedef struct _MyFixedStruct2 {
|
||||
char buffer[1]; // fixed size buffer
|
||||
size_t len;
|
||||
} MyFixedStruct2;
|
||||
|
||||
void testMyFixedStruct2()
|
||||
{
|
||||
MyFixedStruct2 *ptr1 = (MyFixedStruct2 *)malloc(sizeof(MyFixedStruct2));
|
||||
ptr1->len = 1;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // BAD: length 2, but destination only has length 1
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 1
|
||||
// ...
|
||||
|
||||
MyFixedStruct2 *ptr2 = (MyFixedStruct2*)malloc(sizeof(MyFixedStruct2) + (sizeof(char) * 10));
|
||||
ptr2->len = 11;
|
||||
strcpy(ptr2->buffer, "123456789"); // BAD: length 10, but destination only has length 1 [NOT DETECTED]
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 1
|
||||
// ...
|
||||
}
|
||||
Reference in New Issue
Block a user