mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
C++: Add some more test cases (moved from the private repo).
This commit is contained in:
@@ -12,6 +12,16 @@ edges
|
||||
| tests2.cpp:109:6:109:8 | ptr [post update] | tests2.cpp:109:3:109:4 | c1 [post update] [ptr] |
|
||||
| tests2.cpp:109:12:109:17 | call to getenv | tests2.cpp:109:6:109:8 | ptr [post update] |
|
||||
| tests2.cpp:111:14:111:15 | c1 [read] [ptr] | tests2.cpp:111:14:111:19 | (const char *)... |
|
||||
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | (const void *)... |
|
||||
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | path |
|
||||
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | (const void *)... |
|
||||
| tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | path |
|
||||
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | (const void *)... |
|
||||
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | path |
|
||||
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | (const void *)... |
|
||||
| tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | path |
|
||||
| tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | (const void *)... |
|
||||
| tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | pathbuf |
|
||||
nodes
|
||||
| tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv |
|
||||
| tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv |
|
||||
@@ -38,6 +48,19 @@ nodes
|
||||
| tests2.cpp:109:12:109:17 | call to getenv | semmle.label | call to getenv |
|
||||
| tests2.cpp:111:14:111:15 | c1 [read] [ptr] | semmle.label | c1 [read] [ptr] |
|
||||
| tests2.cpp:111:14:111:19 | (const char *)... | semmle.label | (const char *)... |
|
||||
| tests_sockets.cpp:26:15:26:20 | call to getenv | semmle.label | call to getenv |
|
||||
| tests_sockets.cpp:39:19:39:22 | (const void *)... | semmle.label | (const void *)... |
|
||||
| tests_sockets.cpp:39:19:39:22 | path | semmle.label | path |
|
||||
| tests_sockets.cpp:43:20:43:23 | (const void *)... | semmle.label | (const void *)... |
|
||||
| tests_sockets.cpp:43:20:43:23 | path | semmle.label | path |
|
||||
| tests_sockets.cpp:63:15:63:20 | call to getenv | semmle.label | call to getenv |
|
||||
| tests_sockets.cpp:76:19:76:22 | (const void *)... | semmle.label | (const void *)... |
|
||||
| tests_sockets.cpp:76:19:76:22 | path | semmle.label | path |
|
||||
| tests_sockets.cpp:80:20:80:23 | (const void *)... | semmle.label | (const void *)... |
|
||||
| tests_sockets.cpp:80:20:80:23 | path | semmle.label | path |
|
||||
| tests_sysconf.cpp:36:21:36:27 | pathbuf | semmle.label | pathbuf |
|
||||
| tests_sysconf.cpp:39:19:39:25 | (const void *)... | semmle.label | (const void *)... |
|
||||
| tests_sysconf.cpp:39:19:39:25 | pathbuf | semmle.label | pathbuf |
|
||||
subpaths
|
||||
#select
|
||||
| tests2.cpp:63:13:63:18 | call to getenv | tests2.cpp:63:13:63:18 | call to getenv | tests2.cpp:63:13:63:18 | call to getenv | This operation exposes system data from $@. | tests2.cpp:63:13:63:18 | call to getenv | call to getenv |
|
||||
@@ -50,3 +73,8 @@ subpaths
|
||||
| tests2.cpp:93:14:93:17 | str1 | tests2.cpp:91:42:91:45 | str1 | tests2.cpp:93:14:93:17 | str1 | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 | str1 |
|
||||
| tests2.cpp:102:14:102:15 | pw | tests2.cpp:101:8:101:15 | call to getpwuid | tests2.cpp:102:14:102:15 | pw | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid | call to getpwuid |
|
||||
| tests2.cpp:111:14:111:19 | (const char *)... | tests2.cpp:109:12:109:17 | call to getenv | tests2.cpp:111:14:111:19 | (const char *)... | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv | call to getenv |
|
||||
| tests_sockets.cpp:39:19:39:22 | path | tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:39:19:39:22 | path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv | call to getenv |
|
||||
| tests_sockets.cpp:43:20:43:23 | path | tests_sockets.cpp:26:15:26:20 | call to getenv | tests_sockets.cpp:43:20:43:23 | path | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv | call to getenv |
|
||||
| tests_sockets.cpp:76:19:76:22 | path | tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:76:19:76:22 | path | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv | call to getenv |
|
||||
| tests_sockets.cpp:80:20:80:23 | path | tests_sockets.cpp:63:15:63:20 | call to getenv | tests_sockets.cpp:80:20:80:23 | path | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv | call to getenv |
|
||||
| tests_sysconf.cpp:39:19:39:25 | pathbuf | tests_sysconf.cpp:36:21:36:27 | pathbuf | tests_sysconf.cpp:39:19:39:25 | pathbuf | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | pathbuf | pathbuf |
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
// test cases for rule CWE-497
|
||||
|
||||
// library functions etc
|
||||
|
||||
typedef unsigned long size_t;
|
||||
typedef struct {} FILE;
|
||||
FILE *stdout;
|
||||
|
||||
int puts(const char *s);
|
||||
int printf(const char *format, ...);
|
||||
int sprintf(char *s, const char *format, ...);
|
||||
int snprintf(char *s, size_t n, const char *format, ...);
|
||||
size_t strlen(const char *s);
|
||||
char *getenv(const char *name);
|
||||
|
||||
namespace std
|
||||
{
|
||||
typedef size_t streamsize;
|
||||
|
||||
template<class charT> struct char_traits;
|
||||
|
||||
template <class charT, class traits = char_traits<charT> >
|
||||
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
typedef charT char_type;
|
||||
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
|
||||
|
||||
basic_ostream<charT, traits>& operator<<(int n);
|
||||
};
|
||||
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
|
||||
|
||||
typedef basic_ostream<char> ostream;
|
||||
|
||||
extern ostream cout;
|
||||
extern ostream cerr;
|
||||
extern ostream clog;
|
||||
}
|
||||
extern std::ostream someotherostream;
|
||||
|
||||
#define NULL (0)
|
||||
|
||||
// test cases
|
||||
|
||||
void test1()
|
||||
{
|
||||
std::ostream cout_copy = std::cout;
|
||||
|
||||
std::cout << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
|
||||
std::cerr << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
|
||||
std::clog << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
|
||||
someotherostream << getenv("USERPROFILE"); // GOOD: not output
|
||||
cout_copy << getenv("USERPROFILE"); // BAD: outputs USERPROFILE environment variable [NOT DETECTED]
|
||||
|
||||
std::cout << getenv("PATH"); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
std::cout.write(getenv("PATH"), strlen(getenv("PATH"))); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
(std::cout << "PATH = ").write(getenv("PATH"), strlen(getenv("PATH"))); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
std::cout.write("PATH = ", 7) << getenv("PATH"); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
}
|
||||
|
||||
char *global_path = getenv("PATH");
|
||||
char *global_other = "Hello, world!";
|
||||
|
||||
void test2(bool cond)
|
||||
{
|
||||
char *maybe;
|
||||
|
||||
maybe = cond ? global_path : global_other;
|
||||
|
||||
printf("path = '%s'\n", global_path); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
printf("other = '%s'\n", global_other);
|
||||
printf("maybe = '%s'\n", maybe); // BAD: may output PATH environment variable [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
char *path_string = getenv("PATH");
|
||||
char buf[4096];
|
||||
|
||||
// ...
|
||||
snprintf(buf, 4096, "invalid path '%s'\n", path_string);
|
||||
puts(buf); // BAD: outputs PATH environment variable [NOT DETECTED]
|
||||
}
|
||||
|
||||
void myOutputFn(const char *msg)
|
||||
{
|
||||
printf("%s", msg);
|
||||
}
|
||||
|
||||
void myOtherFn(const char *msg)
|
||||
{
|
||||
}
|
||||
|
||||
void test4()
|
||||
{
|
||||
myOutputFn(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
|
||||
myOtherFn(getenv("PATH")); // GOOD: does not output anything.
|
||||
}
|
||||
|
||||
void myOutputFn2(const char *msg)
|
||||
{
|
||||
msg = "";
|
||||
printf("%s", msg);
|
||||
}
|
||||
|
||||
void myOutputFn3(const char *msg)
|
||||
{
|
||||
const char *tmp = msg;
|
||||
|
||||
printf("%s", tmp);
|
||||
}
|
||||
|
||||
void myOutputFn4(const char *msg)
|
||||
{
|
||||
char buffer[4096];
|
||||
|
||||
sprintf(buffer, "log: %s\n", msg);
|
||||
puts(buffer);
|
||||
}
|
||||
|
||||
void myOutputFn5(const char *msg)
|
||||
{
|
||||
printf("%s", msg);
|
||||
msg = "";
|
||||
}
|
||||
|
||||
void test5()
|
||||
{
|
||||
myOutputFn2(getenv("PATH")); // GOOD: myOutputFn2 doesn't actually output the parameter
|
||||
myOutputFn3(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
|
||||
myOutputFn4(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
|
||||
myOutputFn5(getenv("PATH")); // BAD: outputs the PATH environment variable [NOT DETECTED]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
int printf(const char *format, ...);
|
||||
|
||||
struct passwd {
|
||||
char *pw_passwd;
|
||||
char *pw_dir;
|
||||
// ...
|
||||
};
|
||||
|
||||
struct passwd *getpwnam(const char *name);
|
||||
|
||||
void test6(char *username)
|
||||
{
|
||||
passwd *pwd;
|
||||
|
||||
pwd = getpwnam(username);
|
||||
|
||||
printf("pw_passwd = %s\n", pwd->pw_passwd); // BAD [NOT DETECTED]
|
||||
printf("pw_dir = %s\n", pwd->pw_dir); // BAD [NOT DETECTED]
|
||||
printf("sizeof(passwd) = %i\n", sizeof(passwd)); // GOOD
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
size_t strlen(const char *s);
|
||||
char *getenv(const char *name);
|
||||
|
||||
#define AF_INET (2)
|
||||
#define SOCK_STREAM (1)
|
||||
|
||||
struct sockaddr {
|
||||
int sa_family;
|
||||
|
||||
// ...
|
||||
};
|
||||
|
||||
int socket(int domain, int type, int protocol);
|
||||
int connect(int socket, const struct sockaddr *address, size_t address_len);
|
||||
size_t send(int socket, const void *buffer, size_t length, int flags);
|
||||
int write(int handle, const void *buffer, size_t length);
|
||||
|
||||
void test_sockets1()
|
||||
{
|
||||
int sockfd;
|
||||
sockaddr addr_remote;
|
||||
char *msg = "Hello, world!";
|
||||
char *path = getenv("PATH");
|
||||
|
||||
// create socket
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) return;
|
||||
|
||||
// connect socket to a remote address
|
||||
addr_remote.sa_family = AF_INET;
|
||||
// ...
|
||||
if (connect(sockfd, &addr_remote, sizeof(addr_remote)) != 0) return;
|
||||
|
||||
// send something using 'send'
|
||||
if (send(sockfd, msg, strlen(msg) + 1, 0) < 0) return; // GOOD
|
||||
if (send(sockfd, path, strlen(path) + 1, 0) < 0) return; // BAD
|
||||
|
||||
// send something using 'write'
|
||||
if (write(sockfd, msg, strlen(msg) + 1) < 0) return; // GOOD
|
||||
if (write(sockfd, path, strlen(path) + 1) < 0) return; // BAD
|
||||
|
||||
// clean up
|
||||
// ...
|
||||
}
|
||||
|
||||
int mksocket()
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void test_sockets2()
|
||||
{
|
||||
int sockfd;
|
||||
sockaddr addr_remote;
|
||||
char *msg = "Hello, world!";
|
||||
char *path = getenv("PATH");
|
||||
|
||||
// create socket
|
||||
sockfd = mksocket();
|
||||
if (sockfd < 0) return;
|
||||
|
||||
// connect socket to a remote address
|
||||
addr_remote.sa_family = AF_INET;
|
||||
// ...
|
||||
if (connect(sockfd, &addr_remote, sizeof(addr_remote)) != 0) return;
|
||||
|
||||
// send something using 'send'
|
||||
if (send(sockfd, msg, strlen(msg) + 1, 0) < 0) return; // GOOD
|
||||
if (send(sockfd, path, strlen(path) + 1, 0) < 0) return; // BAD
|
||||
|
||||
// send something using 'write'
|
||||
if (write(sockfd, msg, strlen(msg) + 1) < 0) return; // GOOD
|
||||
if (write(sockfd, path, strlen(path) + 1) < 0) return; // BAD
|
||||
|
||||
// clean up
|
||||
// ...
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
typedef unsigned long size_t;
|
||||
typedef signed long ssize_t;
|
||||
void *malloc(size_t size);
|
||||
#define NULL (0)
|
||||
|
||||
int printf(const char *format, ...);
|
||||
size_t strlen(const char *s);
|
||||
|
||||
int get_fd();
|
||||
int write(int handle, const void *buffer, size_t length);
|
||||
|
||||
long sysconf(int name);
|
||||
#define _SC_CHILD_MAX (2)
|
||||
|
||||
size_t confstr(int name, char *buffer, size_t length);
|
||||
#define _CS_PATH (1)
|
||||
|
||||
void test_sc_1()
|
||||
{
|
||||
int value = sysconf(_SC_CHILD_MAX);
|
||||
|
||||
printf("_SC_CHILD_MAX = %i\n", _SC_CHILD_MAX); // GOOD
|
||||
printf("_SC_CHILD_MAX = %i\n", value); // BAD [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_sc_2()
|
||||
{
|
||||
char *pathbuf;
|
||||
size_t n;
|
||||
|
||||
n = confstr(_CS_PATH, NULL, (size_t)0);
|
||||
pathbuf = (char *)malloc(n);
|
||||
if (pathbuf != NULL)
|
||||
{
|
||||
confstr(_CS_PATH, pathbuf, n);
|
||||
|
||||
printf("path: %s", pathbuf); // BAD [NOT DETECTED]
|
||||
write(get_fd(), pathbuf, strlen(pathbuf)); // BAD
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user