Merge remote-tracking branch 'upstream/main' into work

This commit is contained in:
Dave Bartolomeo
2020-10-21 18:22:55 -04:00
94 changed files with 3337 additions and 314 deletions

View File

@@ -13,30 +13,9 @@
*/
import cpp
import semmle.code.cpp.models.Models
class Allocation extends FunctionCall {
Allocation() {
exists(string name |
this.getTarget().hasGlobalOrStdName(name) and
(name = "malloc" or name = "calloc" or name = "realloc")
)
}
private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
this.getArgument(0).getValue().toInt() = result
or
this.getName() = "realloc" and
this.getArgument(1).getValue().toInt() = result
or
this.getName() = "calloc" and
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
}
}
predicate baseType(Allocation alloc, Type base) {
predicate baseType(AllocationExpr alloc, Type base) {
exists(PointerType pointer |
pointer.getBaseType() = base and
(
@@ -54,11 +33,12 @@ predicate decideOnSize(Type t, int size) {
size = min(t.getSize())
}
from Allocation alloc, Type base, int basesize, int allocated
from AllocationExpr alloc, Type base, int basesize, int allocated
where
baseType(alloc, base) and
allocated = alloc.getSize() and
allocated = alloc.getSizeBytes() and
decideOnSize(base, basesize) and
alloc.(FunctionCall).getTarget() instanceof AllocationFunction and // exclude `new` and similar
basesize > allocated
select alloc,
"Type '" + base.getName() + "' is " + basesize.toString() + " bytes, but only " +

View File

@@ -13,25 +13,9 @@
*/
import cpp
import semmle.code.cpp.models.Models
class Allocation extends FunctionCall {
Allocation() { this.getTarget().hasGlobalOrStdName(["malloc", "calloc", "realloc"]) }
private string getName() { this.getTarget().hasGlobalOrStdName(result) }
int getSize() {
this.getName() = "malloc" and
this.getArgument(0).getValue().toInt() = result
or
this.getName() = "realloc" and
this.getArgument(1).getValue().toInt() = result
or
this.getName() = "calloc" and
result = this.getArgument(0).getValue().toInt() * this.getArgument(1).getValue().toInt()
}
}
predicate baseType(Allocation alloc, Type base) {
predicate baseType(AllocationExpr alloc, Type base) {
exists(PointerType pointer |
pointer.getBaseType() = base and
(
@@ -44,16 +28,23 @@ predicate baseType(Allocation alloc, Type base) {
)
}
from Allocation alloc, Type base, int basesize, int allocated
predicate decideOnSize(Type t, int size) {
// If the codebase has more than one type with the same name, it can have more than one size.
size = min(t.getSize())
}
from AllocationExpr alloc, Type base, int basesize, int allocated
where
baseType(alloc, base) and
allocated = alloc.getSize() and
allocated = alloc.getSizeBytes() and
decideOnSize(base, basesize) and
alloc.(FunctionCall).getTarget() instanceof AllocationFunction and // exclude `new` and similar
// If the codebase has more than one type with the same name, check if any matches
not exists(int size | base.getSize() = size |
size = 0 or
(allocated / size) * size = allocated
) and
basesize = min(base.getSize())
not basesize > allocated // covered by SizeCheck.ql
select alloc,
"Allocated memory (" + allocated.toString() + " bytes) is not a multiple of the size of '" +
base.getName() + "' (" + basesize.toString() + " bytes)."

View File

@@ -2,3 +2,4 @@
| test.c:17:20:17:25 | call to malloc | Type 'double' is 8 bytes, but only 5 bytes are allocated. |
| test.c:32:19:32:24 | call to malloc | Type 'float' is 4 bytes, but only 2 bytes are allocated. |
| test.c:33:20:33:25 | call to malloc | Type 'double' is 8 bytes, but only 4 bytes are allocated. |
| test.c:59:15:59:20 | call to malloc | Type 'MyUnion' is 128 bytes, but only 8 bytes are allocated. |

View File

@@ -0,0 +1,4 @@
| test2.c:16:23:16:28 | call to malloc | Allocated memory (27 bytes) is not a multiple of the size of 'long long' (8 bytes). |
| test2.c:17:20:17:25 | call to malloc | Allocated memory (33 bytes) is not a multiple of the size of 'double' (8 bytes). |
| test2.c:32:23:32:28 | call to malloc | Allocated memory (28 bytes) is not a multiple of the size of 'long long' (8 bytes). |
| test2.c:33:20:33:25 | call to malloc | Allocated memory (20 bytes) is not a multiple of the size of 'double' (8 bytes). |

View File

@@ -43,5 +43,18 @@ void good1(void) {
free(dptr);
}
typedef struct _myStruct
{
int x, y;
} MyStruct;
typedef union _myUnion
{
MyStruct ms;
char data[128];
} MyUnion;
void test_union() {
MyUnion *a = malloc(sizeof(MyUnion)); // GOOD
MyUnion *b = malloc(sizeof(MyStruct)); // BAD (too small)
}

View File

@@ -0,0 +1,6 @@
int i = 2000000000;
long j = i * i; // BAD
long k = (long) i * i; // GOOD
long l = (long) (i * i); // permitted as the conversion is explicit
long m = static_cast<long> (i) * i; // GOOD
long n = static_cast<long> (i * i); // permitted as the conversion is explicit

View File

@@ -12,3 +12,4 @@
| IntMultToLong.c:108:14:108:78 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'unsigned long'. |
| IntMultToLong.c:119:14:119:26 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'unsigned long'. |
| IntMultToLong.c:126:14:126:32 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'unsigned long'. |
| IntMultToLong.cpp:2:10:2:14 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long'. |

View File

@@ -3,18 +3,19 @@
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| test.cpp:48:10:48:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:54:12:54:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:57:12:57:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:58:12:58:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:59:12:59:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:60:12:60:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:61:12:61:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:62:12:62:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:64:10:64:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:67:12:67:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:73:12:73:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:79:12:79:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:85:12:85:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:90:12:90:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:107:12:107:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:50:10:50:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:56:12:56:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:59:12:59:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:60:12:60:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:61:12:61:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:62:12:62:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:63:12:63:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:64:12:64:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:66:10:66:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:69:12:69:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:75:12:75:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:81:12:81:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:87:12:87:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:92:12:92:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:109:12:109:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:129:20:129:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |

View File

@@ -2,6 +2,8 @@ extern "C" int printf(const char *fmt, ...);
extern "C" int sprintf(char *buf, const char *fmt, ...);
extern "C" char *gettext (const char *);
#define MYSPRINTF sprintf
bool gettext_debug = false;
const char *messages[] = {
@@ -119,6 +121,13 @@ int main(int argc, char **argv) {
//
//
printf(const_wash("Hello, World\n")); // GOOD
{
char buffer[1024];
MYSPRINTF(buffer, "constant"); // GOOD
MYSPRINTF(buffer, argv[0]); // BAD
}
}
const char *simple_func(const char *str) {

View File

@@ -1,4 +0,0 @@
| test.c:16:23:16:28 | call to malloc | Allocated memory (27 bytes) is not a multiple of the size of 'long long' (8 bytes). |
| test.c:17:20:17:25 | call to malloc | Allocated memory (33 bytes) is not a multiple of the size of 'double' (8 bytes). |
| test.c:32:23:32:28 | call to malloc | Allocated memory (28 bytes) is not a multiple of the size of 'long long' (8 bytes). |
| test.c:33:20:33:25 | call to malloc | Allocated memory (20 bytes) is not a multiple of the size of 'double' (8 bytes). |