Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Reduce duplication from cpp/path-injection #16328

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ module TaintedPathConfig implements DataFlow::ConfigSig {
hasUpperBoundsCheck(checkedVar)
)
}

predicate isBarrierOut(DataFlow::Node node) {
// make sinks barriers so that we only report the closest instance
isSink(node)
MathiasVP marked this conversation as resolved.
Show resolved Hide resolved
}
}

module TaintedPath = TaintTracking::Global<TaintedPathConfig>;
Expand Down
4 changes: 4 additions & 0 deletions cpp/ql/src/change-notes/2024-04-25-path-injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Uncontrolled data used in path expression" query (`cpp/path-injection`) query produces fewer near-duplicate results.
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
edges
| test.c:8:27:8:30 | **argv | test.c:9:23:9:29 | *access to array | provenance | |
| test.c:8:27:8:30 | **argv | test.c:31:22:31:28 | *access to array | provenance | |
| test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | provenance | |
| test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | provenance | |
| test.c:9:23:9:29 | *access to array | test.c:17:11:17:18 | *fileName | provenance | TaintFunction |
| test.c:31:22:31:28 | *access to array | test.c:32:11:32:18 | *fileName | provenance | |
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | provenance | |
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | provenance | |
| test.c:48:21:48:26 | *call to getenv | test.c:48:21:48:26 | *call to getenv | provenance | |
| test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | provenance | |
| test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | provenance | TaintFunction |
| test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | |
| test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | provenance | |
nodes
| test.c:8:27:8:30 | **argv | semmle.label | **argv |
| test.c:9:23:9:29 | *access to array | semmle.label | *access to array |
Expand All @@ -16,11 +21,23 @@ nodes
| test.c:38:11:38:18 | *fileName | semmle.label | *fileName |
| test.c:43:17:43:24 | scanf output argument | semmle.label | scanf output argument |
| test.c:44:11:44:18 | *fileName | semmle.label | *fileName |
| test.c:57:10:57:16 | *access to array | semmle.label | *access to array |
| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv |
| test.c:48:21:48:26 | *call to getenv | semmle.label | *call to getenv |
| test.c:49:11:49:17 | *tainted | semmle.label | *tainted |
| test.c:54:21:54:26 | *call to getenv | semmle.label | *call to getenv |
| test.c:55:11:55:16 | *buffer | semmle.label | *buffer |
| test.c:69:14:69:20 | *access to array | semmle.label | *access to array |
| test.c:74:13:74:18 | read output argument | semmle.label | read output argument |
| test.c:75:13:75:18 | read output argument | semmle.label | read output argument |
| test.c:76:11:76:16 | *buffer | semmle.label | *buffer |
subpaths
#select
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | **argv | test.c:17:11:17:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) |
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | **argv | test.c:32:11:32:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) |
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | *fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | **argv | test.c:57:10:57:16 | *access to array | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) |
| test.c:49:11:49:17 | tainted | test.c:48:21:48:26 | *call to getenv | test.c:49:11:49:17 | *tainted | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:48:21:48:26 | *call to getenv | user input (an environment variable) |
| test.c:55:11:55:16 | buffer | test.c:54:21:54:26 | *call to getenv | test.c:55:11:55:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:54:21:54:26 | *call to getenv | user input (an environment variable) |
| test.c:69:14:69:20 | access to array | test.c:8:27:8:30 | **argv | test.c:69:14:69:20 | *access to array | This argument to a file access function is derived from $@ and then passed to readFile(fileName), which calls fopen(filename). | test.c:8:27:8:30 | **argv | user input (a command-line argument) |
| test.c:76:11:76:16 | buffer | test.c:74:13:74:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:74:13:74:18 | read output argument | user input (buffer read by read) |
| test.c:76:11:76:16 | buffer | test.c:75:13:75:18 | read output argument | test.c:76:11:76:16 | *buffer | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:75:13:75:18 | read output argument | user input (buffer read by read) |
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
typedef struct {} FILE;
#define FILENAME_MAX 1000
typedef unsigned long size_t;
typedef signed long ssize_t;

FILE *fopen(const char *filename, const char *mode);
int sprintf(char *s, const char *format, ...);
Expand All @@ -15,3 +16,4 @@ int scanf(const char *format, ...);
void *malloc(size_t size);
double strtod(const char *ptr, char **endptr);
char *getenv(const char *name);
ssize_t read(int fd, void *buffer, size_t count);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

int main(int argc, char** argv) {
char *userAndFile = argv[2];

{
char fileBuffer[FILENAME_MAX] = "/home/";
char *fileName = fileBuffer;
Expand Down Expand Up @@ -44,6 +44,18 @@ int main(int argc, char** argv) {
fopen(fileName, "wb+"); // BAD
}

{
char *tainted = getenv("A_STRING");
fopen(tainted, "wb+"); // BAD
}

{
char buffer[1024];
strncpy(buffer, getenv("A_STRING"), 1024);
fopen(buffer, "wb+"); // BAD
fopen(buffer, "wb+"); // (we don't want a duplicate result here)
}

{
char *aNumber = getenv("A_NUMBER");
double number = strtod(aNumber, 0);
Expand All @@ -53,11 +65,18 @@ int main(int argc, char** argv) {
}

{
void read(const char *fileName);
read(argv[1]); // BAD
void readFile(const char *fileName);
readFile(argv[1]); // BAD
}

{
char buffer[1024];
read(0, buffer, 1024);
read(0, buffer, 1024);
fopen(buffer, "wb+"); // BAD [duplicated with both sources]
}
}

void read(char *fileName) {
void readFile(char *fileName) {
fopen(fileName, "wb+");
}